aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/9pfs/9p.c80
-rw-r--r--hw/9pfs/9p.h5
-rw-r--r--hw/9pfs/trace-events2
-rw-r--r--hw/arm/cubieboard.c1
-rw-r--r--hw/arm/pxa2xx.c4
-rw-r--r--hw/arm/spitz.c13
-rw-r--r--hw/arm/tosa.c12
-rw-r--r--hw/arm/versatilepb.c9
-rw-r--r--hw/arm/virt-acpi-build.c2
-rw-r--r--hw/arm/virt.c9
-rw-r--r--hw/block/nvme.c4
-rw-r--r--hw/block/xen_disk.c65
-rw-r--r--hw/char/cadence_uart.c3
-rw-r--r--hw/char/xen_console.c30
-rw-r--r--hw/display/milkymist-tmu2.c2
-rw-r--r--hw/display/xenfb.c127
-rw-r--r--hw/gpio/imx_gpio.c2
-rw-r--r--hw/i386/acpi-build.c1
-rw-r--r--hw/i386/kvm/apic.c14
-rw-r--r--hw/i386/kvmvapic.c17
-rw-r--r--hw/microblaze/boot.c1
-rw-r--r--hw/mips/mips_malta.c1
-rw-r--r--hw/misc/milkymist-pfpu.c2
-rw-r--r--hw/net/xen_nic.c36
-rw-r--r--hw/nvram/fw_cfg.c1
-rw-r--r--hw/pci-bridge/pci_expander_bridge.c1
-rw-r--r--hw/ppc/ppc405_boards.c1
-rw-r--r--hw/ppc/ppce500_spin.c6
-rw-r--r--hw/ppc/spapr.c5
-rw-r--r--hw/ppc/spapr_hcall.c12
-rw-r--r--hw/s390x/s390-pci-bus.c14
-rw-r--r--hw/s390x/s390-pci-inst.c25
-rw-r--r--hw/scsi/virtio-scsi-dataplane.c4
-rw-r--r--hw/timer/grlib_gptimer.c1
-rw-r--r--hw/tpm/tpm_passthrough.c6
-rw-r--r--hw/tpm/tpm_tis.c1
-rw-r--r--hw/unicore32/puv3.c1
-rw-r--r--hw/usb/ccid-card-emulated.c3
-rw-r--r--hw/usb/ccid-card-passthru.c6
-rw-r--r--hw/usb/ccid.h2
-rw-r--r--hw/usb/dev-mtp.c1
-rw-r--r--hw/usb/dev-smartcard-reader.c11
-rw-r--r--hw/usb/xen-usb.c46
-rw-r--r--hw/vfio/common.c48
-rw-r--r--hw/vfio/pci.c79
-rw-r--r--hw/vfio/spapr.c2
-rw-r--r--hw/xen/Makefile.objs2
-rw-r--r--hw/xen/xen_backend.c348
-rw-r--r--hw/xen/xen_devconfig.c4
-rw-r--r--hw/xen/xen_pvdev.c316
50 files changed, 786 insertions, 602 deletions
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index e88cf257a2..aea7e9d392 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -325,7 +325,7 @@ static int coroutine_fn v9fs_xattr_fid_clunk(V9fsPDU *pdu, V9fsFidState *fidp)
{
int retval = 0;
- if (fidp->fs.xattr.copied_len == -1) {
+ if (fidp->fs.xattr.xattrwalk_fid) {
/* getxattr/listxattr fid */
goto free_value;
}
@@ -535,7 +535,7 @@ static int coroutine_fn v9fs_mark_fids_unreclaim(V9fsPDU *pdu, V9fsPath *path)
static void coroutine_fn virtfs_reset(V9fsPDU *pdu)
{
V9fsState *s = pdu->s;
- V9fsFidState *fidp = NULL;
+ V9fsFidState *fidp;
/* Free all fids */
while (s->fid_list) {
@@ -548,11 +548,6 @@ static void coroutine_fn virtfs_reset(V9fsPDU *pdu)
free_fid(pdu, fidp);
}
}
- if (fidp) {
- /* One or more unclunked fids found... */
- error_report("9pfs:%s: One or more uncluncked fids "
- "found during reset", __func__);
- }
}
#define P9_QID_TYPE_DIR 0x80
@@ -1361,7 +1356,10 @@ static void coroutine_fn v9fs_walk(void *opaque)
memcpy(&qids[name_idx], &qid, sizeof(qid));
}
if (fid == newfid) {
- BUG_ON(fidp->fid_type != P9_FID_NONE);
+ if (fidp->fid_type != P9_FID_NONE) {
+ err = -EINVAL;
+ goto out;
+ }
v9fs_path_copy(&fidp->path, &path);
} else {
newfidp = alloc_fid(s, newfid);
@@ -1443,7 +1441,10 @@ static void coroutine_fn v9fs_open(void *opaque)
err = -ENOENT;
goto out_nofid;
}
- BUG_ON(fidp->fid_type != P9_FID_NONE);
+ if (fidp->fid_type != P9_FID_NONE) {
+ err = -EINVAL;
+ goto out;
+ }
err = v9fs_co_lstat(pdu, &fidp->path, &stbuf);
if (err < 0) {
@@ -1637,20 +1638,17 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
{
ssize_t err;
size_t offset = 7;
- int read_count;
- int64_t xattr_len;
+ uint64_t read_count;
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
VirtQueueElement *elem = v->elems[pdu->idx];
- xattr_len = fidp->fs.xattr.len;
- read_count = xattr_len - off;
+ if (fidp->fs.xattr.len < off) {
+ read_count = 0;
+ } else {
+ read_count = fidp->fs.xattr.len - off;
+ }
if (read_count > max_count) {
read_count = max_count;
- } else if (read_count < 0) {
- /*
- * read beyond XATTR value
- */
- read_count = 0;
}
err = pdu_marshal(pdu, offset, "d", read_count);
if (err < 0) {
@@ -1979,23 +1977,18 @@ static int v9fs_xattr_write(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
{
int i, to_copy;
ssize_t err = 0;
- int write_count;
- int64_t xattr_len;
+ uint64_t write_count;
size_t offset = 7;
- xattr_len = fidp->fs.xattr.len;
- write_count = xattr_len - off;
- if (write_count > count) {
- write_count = count;
- } else if (write_count < 0) {
- /*
- * write beyond XATTR value len specified in
- * xattrcreate
- */
+ if (fidp->fs.xattr.len < off) {
err = -ENOSPC;
goto out;
}
+ write_count = fidp->fs.xattr.len - off;
+ if (write_count > count) {
+ write_count = count;
+ }
err = pdu_marshal(pdu, offset, "d", write_count);
if (err < 0) {
return err;
@@ -2548,7 +2541,10 @@ static int coroutine_fn v9fs_complete_rename(V9fsPDU *pdu, V9fsFidState *fidp,
err = -ENOENT;
goto out_nofid;
}
- BUG_ON(dirfidp->fid_type != P9_FID_NONE);
+ if (fidp->fid_type != P9_FID_NONE) {
+ err = -EINVAL;
+ goto out;
+ }
v9fs_co_name_to_path(pdu, &dirfidp->path, name->data, &new_path);
} else {
old_name = fidp->path.data;
@@ -2620,7 +2616,10 @@ static void coroutine_fn v9fs_rename(void *opaque)
err = -ENOENT;
goto out_nofid;
}
- BUG_ON(fidp->fid_type != P9_FID_NONE);
+ if (fidp->fid_type != P9_FID_NONE) {
+ err = -EINVAL;
+ goto out;
+ }
/* if fs driver is not path based, return EOPNOTSUPP */
if (!(pdu->s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT)) {
err = -EOPNOTSUPP;
@@ -3190,7 +3189,7 @@ static void coroutine_fn v9fs_xattrwalk(void *opaque)
*/
xattr_fidp->fs.xattr.len = size;
xattr_fidp->fid_type = P9_FID_XATTR;
- xattr_fidp->fs.xattr.copied_len = -1;
+ xattr_fidp->fs.xattr.xattrwalk_fid = true;
if (size) {
xattr_fidp->fs.xattr.value = g_malloc(size);
err = v9fs_co_llistxattr(pdu, &xattr_fidp->path,
@@ -3223,7 +3222,7 @@ static void coroutine_fn v9fs_xattrwalk(void *opaque)
*/
xattr_fidp->fs.xattr.len = size;
xattr_fidp->fid_type = P9_FID_XATTR;
- xattr_fidp->fs.xattr.copied_len = -1;
+ xattr_fidp->fs.xattr.xattrwalk_fid = true;
if (size) {
xattr_fidp->fs.xattr.value = g_malloc(size);
err = v9fs_co_lgetxattr(pdu, &xattr_fidp->path,
@@ -3255,7 +3254,7 @@ static void coroutine_fn v9fs_xattrcreate(void *opaque)
{
int flags;
int32_t fid;
- int64_t size;
+ uint64_t size;
ssize_t err = 0;
V9fsString name;
size_t offset = 7;
@@ -3270,22 +3269,33 @@ static void coroutine_fn v9fs_xattrcreate(void *opaque)
}
trace_v9fs_xattrcreate(pdu->tag, pdu->id, fid, name.data, size, flags);
+ if (size > XATTR_SIZE_MAX) {
+ err = -E2BIG;
+ goto out_nofid;
+ }
+
file_fidp = get_fid(pdu, fid);
if (file_fidp == NULL) {
err = -EINVAL;
goto out_nofid;
}
+ if (file_fidp->fid_type != P9_FID_NONE) {
+ err = -EINVAL;
+ goto out_put_fid;
+ }
+
/* Make the file fid point to xattr */
xattr_fidp = file_fidp;
xattr_fidp->fid_type = P9_FID_XATTR;
xattr_fidp->fs.xattr.copied_len = 0;
+ xattr_fidp->fs.xattr.xattrwalk_fid = false;
xattr_fidp->fs.xattr.len = size;
xattr_fidp->fs.xattr.flags = flags;
v9fs_string_init(&xattr_fidp->fs.xattr.name);
v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name);
- g_free(xattr_fidp->fs.xattr.value);
xattr_fidp->fs.xattr.value = g_malloc0(size);
err = offset;
+out_put_fid:
put_fid(pdu, file_fidp);
out_nofid:
pdu_complete(pdu, err);
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index 2523a445f8..3976b7fe3d 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -159,11 +159,12 @@ typedef struct V9fsConf
typedef struct V9fsXattr
{
- int64_t copied_len;
- int64_t len;
+ uint64_t copied_len;
+ uint64_t len;
void *value;
V9fsString name;
int flags;
+ bool xattrwalk_fid;
} V9fsXattr;
typedef struct V9fsDir {
diff --git a/hw/9pfs/trace-events b/hw/9pfs/trace-events
index 48d3d8abed..fb4de3d465 100644
--- a/hw/9pfs/trace-events
+++ b/hw/9pfs/trace-events
@@ -42,6 +42,6 @@ v9fs_mkdir(uint16_t tag, uint8_t id, int32_t fid, char* name, int mode, uint32_t
v9fs_mkdir_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int err) "tag %u id %u qid={type %d version %d path %"PRId64"} err %d"
v9fs_xattrwalk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, char* name) "tag %d id %d fid %d newfid %d name %s"
v9fs_xattrwalk_return(uint16_t tag, uint8_t id, int64_t size) "tag %d id %d size %"PRId64
-v9fs_xattrcreate(uint16_t tag, uint8_t id, int32_t fid, char* name, int64_t size, int flags) "tag %d id %d fid %d name %s size %"PRId64" flags %d"
+v9fs_xattrcreate(uint16_t tag, uint8_t id, int32_t fid, char* name, uint64_t size, int flags) "tag %d id %d fid %d name %s size %"PRIu64" flags %d"
v9fs_readlink(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
v9fs_readlink_return(uint16_t tag, uint8_t id, char* target) "tag %d id %d name %s"
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index fbd78ed01c..dd19ba3c99 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -74,6 +74,7 @@ static void cubieboard_init(MachineState *machine)
cubieboard_binfo.ram_size = machine->ram_size;
cubieboard_binfo.kernel_filename = machine->kernel_filename;
cubieboard_binfo.kernel_cmdline = machine->kernel_cmdline;
+ cubieboard_binfo.initrd_filename = machine->initrd_filename;
arm_load_kernel(&s->a10->cpu, &cubieboard_binfo);
}
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 42cdde0478..21ea1d6210 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -2267,7 +2267,9 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
s->cm_base = 0x41300000;
- s->cm_regs[CCCR >> 2] = 0x02000210; /* 416.0 MHz */
+ s->cm_regs[CCCR >> 2] = 0x00000121; /* from datasheet */
+ s->cm_regs[CKEN >> 2] = 0x00017def; /* from datasheet */
+
s->clkcfg = 0x00000009; /* Turbo mode active */
memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);
memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 41cc2eeeb1..949a15ae64 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -29,6 +29,7 @@
#include "sysemu/block-backend.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
#undef REG_FMT
#define REG_FMT "0x%02lx"
@@ -844,9 +845,18 @@ static void spitz_lcd_hsync_handler(void *opaque, int line, int level)
spitz_hsync ^= 1;
}
+static void spitz_reset(void *opaque, int line, int level)
+{
+ if (level) {
+ qemu_system_reset_request();
+ }
+}
+
static void spitz_gpio_setup(PXA2xxState *cpu, int slots)
{
qemu_irq lcd_hsync;
+ qemu_irq reset;
+
/*
* Bad hack: We toggle the LCD hsync GPIO on every GPIO status
* read to satisfy broken guests that poll-wait for hsync.
@@ -867,7 +877,8 @@ static void spitz_gpio_setup(PXA2xxState *cpu, int slots)
qemu_irq_raise(qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_BAT_COVER));
/* Handle reset */
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_ON_RESET, cpu->reset);
+ reset = qemu_allocate_irq(spitz_reset, cpu, 0);
+ qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_ON_RESET, reset);
/* PCMCIA signals: card's IRQ and Card-Detect */
if (slots >= 1)
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 2db66508b5..1ee12f49b3 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -25,6 +25,7 @@
#include "sysemu/block-backend.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
#define TOSA_RAM 0x04000000
#define TOSA_ROM 0x00800000
@@ -86,6 +87,12 @@ static void tosa_out_switch(void *opaque, int line, int level)
}
}
+static void tosa_reset(void *opaque, int line, int level)
+{
+ if (level) {
+ qemu_system_reset_request();
+ }
+}
static void tosa_gpio_setup(PXA2xxState *cpu,
DeviceState *scp0,
@@ -93,13 +100,16 @@ static void tosa_gpio_setup(PXA2xxState *cpu,
TC6393xbState *tmio)
{
qemu_irq *outsignals = qemu_allocate_irqs(tosa_out_switch, cpu, 4);
+ qemu_irq reset;
+
/* MMC/SD host */
pxa2xx_mmci_handlers(cpu->mmc,
qdev_get_gpio_in(scp0, TOSA_GPIO_SD_WP),
qemu_irq_invert(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_nSD_DETECT)));
/* Handle reset */
- qdev_connect_gpio_out(cpu->gpio, TOSA_GPIO_ON_RESET, cpu->reset);
+ reset = qemu_allocate_irq(tosa_reset, cpu, 0);
+ qdev_connect_gpio_out(cpu->gpio, TOSA_GPIO_ON_RESET, reset);
/* PCMCIA signals: card's IRQ and Card-Detect */
pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0],
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 8ae5392bcc..7b5cb36d5a 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -198,6 +198,15 @@ static void versatile_init(MachineState *machine, int board_id)
int done_smc = 0;
DriveInfo *dinfo;
+ if (machine->ram_size > 0x10000000) {
+ /* Device starting at address 0x10000000,
+ * and memory cannot overlap with devices.
+ * Refuse to run rather than behaving very confusingly.
+ */
+ error_report("versatilepb: memory size must not exceed 256MB");
+ exit(1);
+ }
+
if (!machine->cpu_model) {
machine->cpu_model = "arm926";
}
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 5fc10df08e..f953610018 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -594,7 +594,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
gicc->uid = i;
gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
- if (armcpu->has_pmu) {
+ if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
}
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 070bbf89d4..54a8b28a58 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -85,6 +85,7 @@ typedef struct {
VirtBoardInfo *daughterboard;
bool disallow_affinity_adjustment;
bool no_its;
+ bool no_pmu;
} VirtMachineClass;
typedef struct {
@@ -490,7 +491,7 @@ static void fdt_add_pmu_nodes(const VirtBoardInfo *vbi, int gictype)
CPU_FOREACH(cpu) {
armcpu = ARM_CPU(cpu);
- if (!armcpu->has_pmu ||
+ if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU) ||
!kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ))) {
return;
}
@@ -1353,6 +1354,10 @@ static void machvirt_init(MachineState *machine)
}
}
+ if (vmc->no_pmu && object_property_find(cpuobj, "pmu", NULL)) {
+ object_property_set_bool(cpuobj, false, "pmu", NULL);
+ }
+
if (object_property_find(cpuobj, "reset-cbar", NULL)) {
object_property_set_int(cpuobj, vbi->memmap[VIRT_CPUPERIPHS].base,
"reset-cbar", &error_abort);
@@ -1592,5 +1597,7 @@ static void virt_machine_2_6_options(MachineClass *mc)
virt_machine_2_7_options(mc);
SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_6);
vmc->disallow_affinity_adjustment = true;
+ /* Disable PMU for 2.6 as PMU support was first introduced in 2.7 */
+ vmc->no_pmu = true;
}
DEFINE_VIRT_MACHINE(2, 6)
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index b380142028..d479fd22f5 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -375,7 +375,7 @@ static uint16_t nvme_create_sq(NvmeCtrl *n, NvmeCmd *cmd)
if (!cqid || nvme_check_cqid(n, cqid)) {
return NVME_INVALID_CQID | NVME_DNR;
}
- if (!sqid || (sqid && !nvme_check_sqid(n, sqid))) {
+ if (!sqid || !nvme_check_sqid(n, sqid)) {
return NVME_INVALID_QID | NVME_DNR;
}
if (!qsize || qsize > NVME_CAP_MQES(n->bar.cap)) {
@@ -449,7 +449,7 @@ static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeCmd *cmd)
uint16_t qflags = le16_to_cpu(c->cq_flags);
uint64_t prp1 = le64_to_cpu(c->prp1);
- if (!cqid || (cqid && !nvme_check_cqid(n, cqid))) {
+ if (!cqid || !nvme_check_cqid(n, cqid)) {
return NVME_INVALID_CQID | NVME_DNR;
}
if (!qsize || qsize > NVME_CAP_MQES(n->bar.cap)) {
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 1292a4b459..3a7dc194e2 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -167,12 +167,12 @@ static void destroy_grant(gpointer pgnt)
xengnttab_handle *gnt = grant->blkdev->xendev.gnttabdev;
if (xengnttab_unmap(gnt, grant->page, 1) != 0) {
- xen_be_printf(&grant->blkdev->xendev, 0,
+ xen_pv_printf(&grant->blkdev->xendev, 0,
"xengnttab_unmap failed: %s\n",
strerror(errno));
}
grant->blkdev->persistent_gnt_count--;
- xen_be_printf(&grant->blkdev->xendev, 3,
+ xen_pv_printf(&grant->blkdev->xendev, 3,
"unmapped grant %p\n", grant->page);
g_free(grant);
}
@@ -184,11 +184,11 @@ static void remove_persistent_region(gpointer data, gpointer dev)
xengnttab_handle *gnt = blkdev->xendev.gnttabdev;
if (xengnttab_unmap(gnt, region->addr, region->num) != 0) {
- xen_be_printf(&blkdev->xendev, 0,
+ xen_pv_printf(&blkdev->xendev, 0,
"xengnttab_unmap region %p failed: %s\n",
region->addr, strerror(errno));
}
- xen_be_printf(&blkdev->xendev, 3,
+ xen_pv_printf(&blkdev->xendev, 3,
"unmapped grant region %p with %d pages\n",
region->addr, region->num);
g_free(region);
@@ -255,7 +255,7 @@ static int ioreq_parse(struct ioreq *ioreq)
size_t len;
int i;
- xen_be_printf(&blkdev->xendev, 3,
+ xen_pv_printf(&blkdev->xendev, 3,
"op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
ioreq->req.operation, ioreq->req.nr_segments,
ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
@@ -275,28 +275,28 @@ static int ioreq_parse(struct ioreq *ioreq)
case BLKIF_OP_DISCARD:
return 0;
default:
- xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
+ xen_pv_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
ioreq->req.operation);
goto err;
};
if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
- xen_be_printf(&blkdev->xendev, 0, "error: write req for ro device\n");
+ xen_pv_printf(&blkdev->xendev, 0, "error: write req for ro device\n");
goto err;
}
ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
for (i = 0; i < ioreq->req.nr_segments; i++) {
if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
- xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
+ xen_pv_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
goto err;
}
if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
- xen_be_printf(&blkdev->xendev, 0, "error: first > last sector\n");
+ xen_pv_printf(&blkdev->xendev, 0, "error: first > last sector\n");
goto err;
}
if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
- xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n");
+ xen_pv_printf(&blkdev->xendev, 0, "error: page crossing\n");
goto err;
}
@@ -308,7 +308,7 @@ static int ioreq_parse(struct ioreq *ioreq)
qemu_iovec_add(&ioreq->v, (void*)mem, len);
}
if (ioreq->start + ioreq->v.size > blkdev->file_size) {
- xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
+ xen_pv_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
goto err;
}
return 0;
@@ -331,7 +331,7 @@ static void ioreq_unmap(struct ioreq *ioreq)
return;
}
if (xengnttab_unmap(gnt, ioreq->pages, ioreq->num_unmap) != 0) {
- xen_be_printf(&ioreq->blkdev->xendev, 0,
+ xen_pv_printf(&ioreq->blkdev->xendev, 0,
"xengnttab_unmap failed: %s\n",
strerror(errno));
}
@@ -343,7 +343,7 @@ static void ioreq_unmap(struct ioreq *ioreq)
continue;
}
if (xengnttab_unmap(gnt, ioreq->page[i], 1) != 0) {
- xen_be_printf(&ioreq->blkdev->xendev, 0,
+ xen_pv_printf(&ioreq->blkdev->xendev, 0,
"xengnttab_unmap failed: %s\n",
strerror(errno));
}
@@ -381,7 +381,7 @@ static int ioreq_map(struct ioreq *ioreq)
if (grant != NULL) {
page[i] = grant->page;
- xen_be_printf(&ioreq->blkdev->xendev, 3,
+ xen_pv_printf(&ioreq->blkdev->xendev, 3,
"using persistent-grant %" PRIu32 "\n",
ioreq->refs[i]);
} else {
@@ -410,7 +410,7 @@ static int ioreq_map(struct ioreq *ioreq)
ioreq->pages = xengnttab_map_grant_refs
(gnt, new_maps, domids, refs, ioreq->prot);
if (ioreq->pages == NULL) {
- xen_be_printf(&ioreq->blkdev->xendev, 0,
+ xen_pv_printf(&ioreq->blkdev->xendev, 0,
"can't map %d grant refs (%s, %d maps)\n",
new_maps, strerror(errno), ioreq->blkdev->cnt_map);
return -1;
@@ -426,7 +426,7 @@ static int ioreq_map(struct ioreq *ioreq)
ioreq->page[i] = xengnttab_map_grant_ref
(gnt, domids[i], refs[i], ioreq->prot);
if (ioreq->page[i] == NULL) {
- xen_be_printf(&ioreq->blkdev->xendev, 0,
+ xen_pv_printf(&ioreq->blkdev->xendev, 0,
"can't map grant ref %d (%s, %d maps)\n",
refs[i], strerror(errno), ioreq->blkdev->cnt_map);
ioreq->mapped = 1;
@@ -474,7 +474,7 @@ static int ioreq_map(struct ioreq *ioreq)
grant->page = ioreq->page[new_maps];
}
grant->blkdev = ioreq->blkdev;
- xen_be_printf(&ioreq->blkdev->xendev, 3,
+ xen_pv_printf(&ioreq->blkdev->xendev, 3,
"adding grant %" PRIu32 " page: %p\n",
refs[new_maps], grant->page);
g_tree_insert(ioreq->blkdev->persistent_gnts,
@@ -557,7 +557,7 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
rc = xengnttab_grant_copy(gnt, count, segs);
if (rc) {
- xen_be_printf(&ioreq->blkdev->xendev, 0,
+ xen_pv_printf(&ioreq->blkdev->xendev, 0,
"failed to copy data %d\n", rc);
ioreq->aio_errors++;
return -1;
@@ -565,7 +565,7 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
for (i = 0; i < count; i++) {
if (segs[i].status != GNTST_okay) {
- xen_be_printf(&ioreq->blkdev->xendev, 3,
+ xen_pv_printf(&ioreq->blkdev->xendev, 3,
"failed to copy data %d for gref %d, domid %d\n",
segs[i].status, ioreq->refs[i], ioreq->domids[i]);
ioreq->aio_errors++;
@@ -599,7 +599,7 @@ static void qemu_aio_complete(void *opaque, int ret)
struct ioreq *ioreq = opaque;
if (ret != 0) {
- xen_be_printf(&ioreq->blkdev->xendev, 0, "%s I/O error\n",
+ xen_pv_printf(&ioreq->blkdev->xendev, 0, "%s I/O error\n",
ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
ioreq->aio_errors++;
}
@@ -796,7 +796,7 @@ static void blk_send_response_all(struct XenBlkDev *blkdev)
ioreq_release(ioreq, true);
}
if (send_notify) {
- xen_be_send_notify(&blkdev->xendev);
+ xen_pv_send_notify(&blkdev->xendev);
}
}
@@ -866,7 +866,7 @@ static void blk_handle_requests(struct XenBlkDev *blkdev)
};
if (blk_send_response_one(ioreq)) {
- xen_be_send_notify(&blkdev->xendev);
+ xen_pv_send_notify(&blkdev->xendev);
}
ioreq_release(ioreq, false);
continue;
@@ -910,7 +910,7 @@ static void blk_alloc(struct XenDevice *xendev)
}
if (xengnttab_set_max_grants(xendev->gnttabdev,
MAX_GRANTS(max_requests, BLKIF_MAX_SEGMENTS_PER_REQUEST)) < 0) {
- xen_be_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
+ xen_pv_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
strerror(errno));
}
}
@@ -1056,11 +1056,11 @@ static int blk_connect(struct XenDevice *xendev)
}
/* setup via xenbus -> create new block driver instance */
- xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
+ xen_pv_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
blkdev->blk = blk_new_open(blkdev->filename, NULL, options,
qflags, &local_err);
if (!blkdev->blk) {
- xen_be_printf(&blkdev->xendev, 0, "error: %s\n",
+ xen_pv_printf(&blkdev->xendev, 0, "error: %s\n",
error_get_pretty(local_err));
error_free(local_err);
return -1;
@@ -1068,10 +1068,11 @@ static int blk_connect(struct XenDevice *xendev)
blk_set_enable_write_cache(blkdev->blk, !writethrough);
} else {
/* setup via qemu cmdline -> already setup for us */
- xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
+ xen_pv_printf(&blkdev->xendev, 2,
+ "get configured bdrv (cmdline setup)\n");
blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo);
if (blk_is_read_only(blkdev->blk) && !readonly) {
- xen_be_printf(&blkdev->xendev, 0, "Unexpected read-only drive");
+ xen_pv_printf(&blkdev->xendev, 0, "Unexpected read-only drive");
blkdev->blk = NULL;
return -1;
}
@@ -1084,13 +1085,13 @@ static int blk_connect(struct XenDevice *xendev)
if (blkdev->file_size < 0) {
BlockDriverState *bs = blk_bs(blkdev->blk);
const char *drv_name = bs ? bdrv_get_format_name(bs) : NULL;
- xen_be_printf(&blkdev->xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
+ xen_pv_printf(&blkdev->xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
(int)blkdev->file_size, strerror(-blkdev->file_size),
drv_name ?: "-");
blkdev->file_size = 0;
}
- xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
+ xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
" size %" PRId64 " (%" PRId64 " MB)\n",
blkdev->type, blkdev->fileproto, blkdev->filename,
blkdev->file_size, blkdev->file_size >> 20);
@@ -1174,10 +1175,10 @@ static int blk_connect(struct XenDevice *xendev)
blkdev->feature_grant_copy =
(xengnttab_grant_copy(blkdev->xendev.gnttabdev, 0, NULL) == 0);
- xen_be_printf(&blkdev->xendev, 3, "grant copy operation %s\n",
+ xen_pv_printf(&blkdev->xendev, 3, "grant copy operation %s\n",
blkdev->feature_grant_copy ? "enabled" : "disabled");
- xen_be_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, "
+ xen_pv_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, "
"remote port %d, local port %d\n",
blkdev->xendev.protocol, blkdev->ring_ref,
blkdev->xendev.remote_port, blkdev->xendev.local_port);
@@ -1193,7 +1194,7 @@ static void blk_disconnect(struct XenDevice *xendev)
blk_unref(blkdev->blk);
blkdev->blk = NULL;
}
- xen_be_unbind_evtchn(&blkdev->xendev);
+ xen_pv_unbind_evtchn(&blkdev->xendev);
if (blkdev->sring) {
xengnttab_unmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index c2b9154305..def34cd0d2 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -450,7 +450,8 @@ static void cadence_uart_reset(DeviceState *dev)
s->r[R_IMR] = 0;
s->r[R_CISR] = 0;
s->r[R_RTRIG] = 0x00000020;
- s->r[R_BRGR] = 0x0000000F;
+ s->r[R_BRGR] = 0x0000028B;
+ s->r[R_BDIV] = 0x0000000F;
s->r[R_TTRIG] = 0x00000020;
uart_rx_reset(s);
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index 86cdc529a3..c01f41090e 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -74,7 +74,7 @@ static void buffer_append(struct XenConsole *con)
xen_mb();
intf->out_cons = cons;
- xen_be_send_notify(&con->xendev);
+ xen_pv_send_notify(&con->xendev);
if (buffer->max_capacity &&
buffer->size > buffer->max_capacity) {
@@ -142,7 +142,7 @@ static void xencons_receive(void *opaque, const uint8_t *buf, int len)
}
xen_wmb();
intf->in_prod = prod;
- xen_be_send_notify(&con->xendev);
+ xen_pv_send_notify(&con->xendev);
}
static void xencons_send(struct XenConsole *con)
@@ -158,16 +158,17 @@ static void xencons_send(struct XenConsole *con)
len = size;
}
if (len < 1) {
- if (!con->backlog) {
- con->backlog = 1;
- xen_be_printf(&con->xendev, 1, "backlog piling up, nobody listening?\n");
- }
+ if (!con->backlog) {
+ con->backlog = 1;
+ xen_pv_printf(&con->xendev, 1,
+ "backlog piling up, nobody listening?\n");
+ }
} else {
- buffer_advance(&con->buffer, len);
- if (con->backlog && len == size) {
- con->backlog = 0;
- xen_be_printf(&con->xendev, 1, "backlog is gone\n");
- }
+ buffer_advance(&con->buffer, len);
+ if (con->backlog && len == size) {
+ con->backlog = 0;
+ xen_pv_printf(&con->xendev, 1, "backlog is gone\n");
+ }
}
}
@@ -191,7 +192,7 @@ 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);
+ xen_pv_printf(xendev, 1, "not for me (type=%s)\n", type);
ret = -1;
goto out;
}
@@ -247,7 +248,8 @@ static int con_initialise(struct XenDevice *xendev)
qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
xencons_receive, NULL, con, NULL, true);
- xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
+ xen_pv_printf(xendev, 1,
+ "ring mfn %d, remote port %d, local port %d, limit %zd\n",
con->ring_ref,
con->xendev.remote_port,
con->xendev.local_port,
@@ -260,7 +262,7 @@ static void con_disconnect(struct XenDevice *xendev)
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
qemu_chr_fe_deinit(&con->chr);
- xen_be_unbind_evtchn(&con->xendev);
+ xen_pv_unbind_evtchn(&con->xendev);
if (con->sring) {
if (!xendev->dev) {
diff --git a/hw/display/milkymist-tmu2.c b/hw/display/milkymist-tmu2.c
index 9c0018448a..5c666f9b24 100644
--- a/hw/display/milkymist-tmu2.c
+++ b/hw/display/milkymist-tmu2.c
@@ -213,7 +213,7 @@ static void tmu2_start(MilkymistTMU2State *s)
/* Read the QEMU source framebuffer into an OpenGL texture */
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
- fb_len = 2*s->regs[R_TEXHRES]*s->regs[R_TEXVRES];
+ fb_len = 2ULL * s->regs[R_TEXHRES] * s->regs[R_TEXVRES];
fb = cpu_physical_memory_map(s->regs[R_TEXFBUF], &fb_len, 0);
if (fb == NULL) {
glDeleteTextures(1, &texture);
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 46b7d5eded..7a8727aa21 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -90,28 +90,29 @@ static int common_bind(struct common *c)
xen_pfn_t mfn;
if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &val) == -1)
- return -1;
+ return -1;
mfn = (xen_pfn_t)val;
assert(val == mfn);
if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1)
- return -1;
+ return -1;
c->page = xenforeignmemory_map(xen_fmem, c->xendev.dom,
PROT_READ | PROT_WRITE, 1, &mfn, NULL);
if (c->page == NULL)
- return -1;
+ return -1;
xen_be_bind_evtchn(&c->xendev);
- xen_be_printf(&c->xendev, 1, "ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n",
- mfn, c->xendev.remote_port, c->xendev.local_port);
+ xen_pv_printf(&c->xendev, 1,
+ "ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n",
+ mfn, c->xendev.remote_port, c->xendev.local_port);
return 0;
}
static void common_unbind(struct common *c)
{
- xen_be_unbind_evtchn(&c->xendev);
+ xen_pv_unbind_evtchn(&c->xendev);
if (c->page) {
xenforeignmemory_unmap(xen_fmem, c->page, 1);
c->page = NULL;
@@ -214,7 +215,7 @@ static int xenfb_kbd_event(struct XenInput *xenfb,
XENKBD_IN_RING_REF(page, prod) = *event;
xen_wmb(); /* ensure ring contents visible */
page->in_prod = prod + 1;
- return xen_be_send_notify(&xenfb->c.xendev);
+ return xen_pv_send_notify(&xenfb->c.xendev);
}
/* Send a keyboard (or mouse button) event */
@@ -345,7 +346,7 @@ static int input_initialise(struct XenDevice *xendev)
int rc;
if (!in->c.con) {
- xen_be_printf(xendev, 1, "ds not set (yet)\n");
+ xen_pv_printf(xendev, 1, "ds not set (yet)\n");
return -1;
}
@@ -396,7 +397,7 @@ static void input_event(struct XenDevice *xendev)
if (page->out_prod == page->out_cons)
return;
page->out_cons = page->out_prod;
- xen_be_send_notify(&xenfb->c.xendev);
+ xen_pv_send_notify(&xenfb->c.xendev);
}
/* -------------------------------------------------------------------- */
@@ -500,8 +501,8 @@ out:
}
static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
- int width, int height, int depth,
- size_t fb_len, int offset, int row_stride)
+ int width, int height, int depth,
+ size_t fb_len, int offset, int row_stride)
{
size_t mfn_sz = sizeof(*((struct xenfb_page *)0)->pd);
size_t pd_len = sizeof(((struct xenfb_page *)0)->pd) / mfn_sz;
@@ -510,40 +511,47 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
int max_width, max_height;
if (fb_len_lim > fb_len_max) {
- xen_be_printf(&xenfb->c.xendev, 0, "fb size limit %zu exceeds %zu, corrected\n",
- fb_len_lim, fb_len_max);
- fb_len_lim = fb_len_max;
+ xen_pv_printf(&xenfb->c.xendev, 0,
+ "fb size limit %zu exceeds %zu, corrected\n",
+ fb_len_lim, fb_len_max);
+ fb_len_lim = fb_len_max;
}
if (fb_len_lim && fb_len > fb_len_lim) {
- xen_be_printf(&xenfb->c.xendev, 0, "frontend fb size %zu limited to %zu\n",
- fb_len, fb_len_lim);
- fb_len = fb_len_lim;
+ xen_pv_printf(&xenfb->c.xendev, 0,
+ "frontend fb size %zu limited to %zu\n",
+ fb_len, fb_len_lim);
+ fb_len = fb_len_lim;
}
if (depth != 8 && depth != 16 && depth != 24 && depth != 32) {
- xen_be_printf(&xenfb->c.xendev, 0, "can't handle frontend fb depth %d\n",
- depth);
- return -1;
+ xen_pv_printf(&xenfb->c.xendev, 0,
+ "can't handle frontend fb depth %d\n",
+ depth);
+ return -1;
}
if (row_stride <= 0 || row_stride > fb_len) {
- xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend stride %d\n", row_stride);
- return -1;
+ xen_pv_printf(&xenfb->c.xendev, 0, "invalid frontend stride %d\n",
+ row_stride);
+ return -1;
}
max_width = row_stride / (depth / 8);
if (width < 0 || width > max_width) {
- xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend width %d limited to %d\n",
- width, max_width);
- width = max_width;
+ xen_pv_printf(&xenfb->c.xendev, 0,
+ "invalid frontend width %d limited to %d\n",
+ width, max_width);
+ width = max_width;
}
if (offset < 0 || offset >= fb_len) {
- xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend offset %d (max %zu)\n",
- offset, fb_len - 1);
- return -1;
+ xen_pv_printf(&xenfb->c.xendev, 0,
+ "invalid frontend offset %d (max %zu)\n",
+ offset, fb_len - 1);
+ return -1;
}
max_height = (fb_len - offset) / row_stride;
if (height < 0 || height > max_height) {
- xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend height %d limited to %d\n",
- height, max_height);
- height = max_height;
+ xen_pv_printf(&xenfb->c.xendev, 0,
+ "invalid frontend height %d limited to %d\n",
+ height, max_height);
+ height = max_height;
}
xenfb->fb_len = fb_len;
xenfb->row_stride = row_stride;
@@ -553,8 +561,9 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
xenfb->offset = offset;
xenfb->up_fullscreen = 1;
xenfb->do_resize = 1;
- xen_be_printf(&xenfb->c.xendev, 1, "framebuffer %dx%dx%d offset %d stride %d\n",
- width, height, depth, offset, row_stride);
+ xen_pv_printf(&xenfb->c.xendev, 1,
+ "framebuffer %dx%dx%d offset %d stride %d\n",
+ width, height, depth, offset, row_stride);
return 0;
}
@@ -631,7 +640,7 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
}
}
if (oops) /* should not happen */
- xen_be_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
+ xen_pv_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
__FUNCTION__, xenfb->depth, bpp);
dpy_gfx_update(xenfb->c.con, x, y, w, h);
@@ -663,7 +672,7 @@ static void xenfb_send_event(struct XenFB *xenfb, union xenfb_in_event *event)
xen_wmb(); /* ensure ring contents visible */
page->in_prod = prod + 1;
- xen_be_send_notify(&xenfb->c.xendev);
+ xen_pv_send_notify(&xenfb->c.xendev);
}
static void xenfb_send_refresh_period(struct XenFB *xenfb, int period)
@@ -696,9 +705,9 @@ static void xenfb_update(void *opaque)
return;
if (!xenfb->feature_update) {
- /* we don't get update notifications, thus use the
- * sledge hammer approach ... */
- xenfb->up_fullscreen = 1;
+ /* we don't get update notifications, thus use the
+ * sledge hammer approach ... */
+ xenfb->up_fullscreen = 1;
}
/* resize if needed */
@@ -721,7 +730,8 @@ static void xenfb_update(void *opaque)
break;
}
dpy_gfx_replace_surface(xenfb->c.con, surface);
- xen_be_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d @ %d bpp%s\n",
+ xen_pv_printf(&xenfb->c.xendev, 1,
+ "update: resizing: %dx%d @ %d bpp%s\n",
xenfb->width, xenfb->height, xenfb->depth,
is_buffer_shared(surface) ? " (shared)" : "");
xenfb->up_fullscreen = 1;
@@ -729,18 +739,19 @@ static void xenfb_update(void *opaque)
/* run queued updates */
if (xenfb->up_fullscreen) {
- xen_be_printf(&xenfb->c.xendev, 3, "update: fullscreen\n");
- xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
+ xen_pv_printf(&xenfb->c.xendev, 3, "update: fullscreen\n");
+ xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
} else if (xenfb->up_count) {
- xen_be_printf(&xenfb->c.xendev, 3, "update: %d rects\n", xenfb->up_count);
- for (i = 0; i < xenfb->up_count; i++)
- xenfb_guest_copy(xenfb,
- xenfb->up_rects[i].x,
- xenfb->up_rects[i].y,
- xenfb->up_rects[i].w,
- xenfb->up_rects[i].h);
+ xen_pv_printf(&xenfb->c.xendev, 3, "update: %d rects\n",
+ xenfb->up_count);
+ for (i = 0; i < xenfb->up_count; i++)
+ xenfb_guest_copy(xenfb,
+ xenfb->up_rects[i].x,
+ xenfb->up_rects[i].y,
+ xenfb->up_rects[i].w,
+ xenfb->up_rects[i].h);
} else {
- xen_be_printf(&xenfb->c.xendev, 3, "update: nothing\n");
+ xen_pv_printf(&xenfb->c.xendev, 3, "update: nothing\n");
}
xenfb->up_count = 0;
xenfb->up_fullscreen = 0;
@@ -794,14 +805,14 @@ static void xenfb_handle_events(struct XenFB *xenfb)
w = MIN(event->update.width, xenfb->width - x);
h = MIN(event->update.height, xenfb->height - y);
if (w < 0 || h < 0) {
- xen_be_printf(&xenfb->c.xendev, 1, "bogus update ignored\n");
+ xen_pv_printf(&xenfb->c.xendev, 1, "bogus update ignored\n");
break;
}
if (x != event->update.x ||
y != event->update.y ||
w != event->update.width ||
h != event->update.height) {
- xen_be_printf(&xenfb->c.xendev, 1, "bogus update clipped\n");
+ xen_pv_printf(&xenfb->c.xendev, 1, "bogus update clipped\n");
}
if (w == xenfb->width && h > xenfb->height / 2) {
/* scroll detector: updated more than 50% of the lines,
@@ -883,7 +894,7 @@ static int fb_initialise(struct XenDevice *xendev)
if (fb->feature_update)
xenstore_write_be_int(xendev, "request-update", 1);
- xen_be_printf(xendev, 1, "feature-update=%d, videoram=%d\n",
+ xen_pv_printf(xendev, 1, "feature-update=%d, videoram=%d\n",
fb->feature_update, videoram);
return 0;
}
@@ -902,7 +913,7 @@ static void fb_disconnect(struct XenDevice *xendev)
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
-1, 0);
if (fb->pixels == MAP_FAILED) {
- xen_be_printf(xendev, 0,
+ xen_pv_printf(xendev, 0,
"Couldn't replace the framebuffer with anonymous memory errno=%d\n",
errno);
}
@@ -923,7 +934,7 @@ static void fb_frontend_changed(struct XenDevice *xendev, const char *node)
if (fb->bug_trigger == 0 && strcmp(node, "state") == 0 &&
xendev->fe_state == XenbusStateConnected &&
xendev->be_state == XenbusStateConnected) {
- xen_be_printf(xendev, 2, "re-trigger connected (frontend bug)\n");
+ xen_pv_printf(xendev, 2, "re-trigger connected (frontend bug)\n");
xen_be_set_state(xendev, XenbusStateConnected);
fb->bug_trigger = 1; /* only once */
}
@@ -934,7 +945,7 @@ static void fb_event(struct XenDevice *xendev)
struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev);
xenfb_handle_events(xenfb);
- xen_be_send_notify(&xenfb->c.xendev);
+ xen_pv_send_notify(&xenfb->c.xendev);
}
/* -------------------------------------------------------------------- */
@@ -977,14 +988,14 @@ void xen_init_display(int domid)
wait_more:
i++;
main_loop_wait(true);
- xfb = xen_be_find_xendev("vfb", domid, 0);
- xin = xen_be_find_xendev("vkbd", domid, 0);
+ xfb = xen_pv_find_xendev("vfb", domid, 0);
+ xin = xen_pv_find_xendev("vkbd", domid, 0);
if (!xfb || !xin) {
if (i < 256) {
usleep(10000);
goto wait_more;
}
- xen_be_printf(NULL, 1, "displaystate setup failed\n");
+ xen_pv_printf(NULL, 1, "displaystate setup failed\n");
return;
}
diff --git a/hw/gpio/imx_gpio.c b/hw/gpio/imx_gpio.c
index f3574aa8f3..c36c394fda 100644
--- a/hw/gpio/imx_gpio.c
+++ b/hw/gpio/imx_gpio.c
@@ -237,7 +237,7 @@ static void imx_gpio_write(void *opaque, hwaddr offset, uint64_t value,
break;
case ISR_ADDR:
- s->isr |= ~value;
+ s->isr &= ~value;
imx_gpio_set_all_int_lines(s);
break;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 7aaa07a177..ce9cc93af4 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -53,7 +53,6 @@
#include "hw/pci/pci_bus.h"
#include "hw/pci-host/q35.h"
#include "hw/i386/x86-iommu.h"
-#include "hw/timer/hpet.h"
#include "hw/acpi/aml-build.h"
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index 39b73e7b3d..01cbaa88d2 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -133,9 +133,9 @@ static void kvm_apic_vapic_base_update(APICCommonState *s)
}
}
-static void kvm_apic_put(CPUState *cs, void *data)
+static void kvm_apic_put(CPUState *cs, run_on_cpu_data data)
{
- APICCommonState *s = data;
+ APICCommonState *s = data.host_ptr;
struct kvm_lapic_state kapic;
int ret;
@@ -151,12 +151,12 @@ static void kvm_apic_put(CPUState *cs, void *data)
static void kvm_apic_post_load(APICCommonState *s)
{
- run_on_cpu(CPU(s->cpu), kvm_apic_put, s);
+ run_on_cpu(CPU(s->cpu), kvm_apic_put, RUN_ON_CPU_HOST_PTR(s));
}
-static void do_inject_external_nmi(CPUState *cpu, void *data)
+static void do_inject_external_nmi(CPUState *cpu, run_on_cpu_data data)
{
- APICCommonState *s = data;
+ APICCommonState *s = data.host_ptr;
uint32_t lvt;
int ret;
@@ -174,7 +174,7 @@ static void do_inject_external_nmi(CPUState *cpu, void *data)
static void kvm_apic_external_nmi(APICCommonState *s)
{
- run_on_cpu(CPU(s->cpu), do_inject_external_nmi, s);
+ run_on_cpu(CPU(s->cpu), do_inject_external_nmi, RUN_ON_CPU_HOST_PTR(s));
}
static void kvm_send_msi(MSIMessage *msg)
@@ -213,7 +213,7 @@ static void kvm_apic_reset(APICCommonState *s)
/* Not used by KVM, which uses the CPU mp_state instead. */
s->wait_for_sipi = 0;
- run_on_cpu(CPU(s->cpu), kvm_apic_put, s);
+ run_on_cpu(CPU(s->cpu), kvm_apic_put, RUN_ON_CPU_HOST_PTR(s));
}
static void kvm_apic_realize(DeviceState *dev, Error **errp)
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 74a549becf..b30d1b90c6 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -17,6 +17,7 @@
#include "sysemu/kvm.h"
#include "hw/i386/apic_internal.h"
#include "hw/sysbus.h"
+#include "tcg/tcg.h"
#define VAPIC_IO_PORT 0x7e
@@ -449,6 +450,9 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
resume_all_vcpus();
if (!kvm_enabled()) {
+ /* tb_lock will be reset when cpu_loop_exit_noexc longjmps
+ * back into the cpu_exec loop. */
+ tb_lock();
tb_gen_code(cs, current_pc, current_cs_base, current_flags, 1);
cpu_loop_exit_noexc(cs);
}
@@ -483,10 +487,9 @@ typedef struct VAPICEnableTPRReporting {
bool enable;
} VAPICEnableTPRReporting;
-static void vapic_do_enable_tpr_reporting(CPUState *cpu, void *data)
+static void vapic_do_enable_tpr_reporting(CPUState *cpu, run_on_cpu_data data)
{
- VAPICEnableTPRReporting *info = data;
-
+ VAPICEnableTPRReporting *info = data.host_ptr;
apic_enable_tpr_access_reporting(info->apic, info->enable);
}
@@ -501,7 +504,7 @@ static void vapic_enable_tpr_reporting(bool enable)
CPU_FOREACH(cs) {
cpu = X86_CPU(cs);
info.apic = cpu->apic_state;
- run_on_cpu(cs, vapic_do_enable_tpr_reporting, &info);
+ run_on_cpu(cs, vapic_do_enable_tpr_reporting, RUN_ON_CPU_HOST_PTR(&info));
}
}
@@ -734,9 +737,9 @@ static void vapic_realize(DeviceState *dev, Error **errp)
nb_option_roms++;
}
-static void do_vapic_enable(CPUState *cs, void *data)
+static void do_vapic_enable(CPUState *cs, run_on_cpu_data data)
{
- VAPICROMState *s = data;
+ VAPICROMState *s = data.host_ptr;
X86CPU *cpu = X86_CPU(cs);
static const uint8_t enabled = 1;
@@ -758,7 +761,7 @@ static void kvmvapic_vm_state_change(void *opaque, int running,
if (s->state == VAPIC_ACTIVE) {
if (smp_cpus == 1) {
- run_on_cpu(first_cpu, do_vapic_enable, s);
+ run_on_cpu(first_cpu, do_vapic_enable, RUN_ON_CPU_HOST_PTR(s));
} else {
zero = g_malloc0(s->rom_state.vapic_size);
cpu_physical_memory_write(s->vapic_paddr, zero,
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 9eebb1a521..1834d22a61 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -30,7 +30,6 @@
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
-#include "qemu-common.h"
#include "sysemu/device_tree.h"
#include "sysemu/sysemu.h"
#include "hw/loader.h"
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index cf9bd3eb45..cf48f420cc 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -47,7 +47,6 @@
#include "elf.h"
#include "hw/timer/mc146818rtc.h"
#include "hw/timer/i8254.h"
-#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "exec/address-spaces.h"
#include "hw/sysbus.h" /* SysBusDevice */
diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c
index 1da21a643e..3ca25894f1 100644
--- a/hw/misc/milkymist-pfpu.c
+++ b/hw/misc/milkymist-pfpu.c
@@ -137,7 +137,7 @@ struct MilkymistPFPUState {
};
typedef struct MilkymistPFPUState MilkymistPFPUState;
-static inline hwaddr
+static inline uint32_t
get_dma_address(uint32_t base, uint32_t x, uint32_t y)
{
return base + 8 * (128 * y + x);
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
index 6856b52999..20c43a61b3 100644
--- a/hw/net/xen_nic.c
+++ b/hw/net/xen_nic.c
@@ -69,7 +69,7 @@ static void net_tx_response(struct XenNetDev *netdev, netif_tx_request_t *txp, i
netdev->tx_ring.rsp_prod_pvt = ++i;
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->tx_ring, notify);
if (notify) {
- xen_be_send_notify(&netdev->xendev);
+ xen_pv_send_notify(&netdev->xendev);
}
if (i == netdev->tx_ring.req_cons) {
@@ -128,30 +128,32 @@ static void net_tx_packets(struct XenNetDev *netdev)
/* should not happen in theory, we don't announce the *
* feature-{sg,gso,whatelse} flags in xenstore (yet?) */
if (txreq.flags & NETTXF_extra_info) {
- xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
+ xen_pv_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
net_tx_error(netdev, &txreq, rc);
continue;
}
if (txreq.flags & NETTXF_more_data) {
- xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
+ xen_pv_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
net_tx_error(netdev, &txreq, rc);
continue;
}
#endif
if (txreq.size < 14) {
- xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size);
+ xen_pv_printf(&netdev->xendev, 0, "bad packet size: %d\n",
+ txreq.size);
net_tx_error(netdev, &txreq, rc);
continue;
}
if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) {
- xen_be_printf(&netdev->xendev, 0, "error: page crossing\n");
+ xen_pv_printf(&netdev->xendev, 0, "error: page crossing\n");
net_tx_error(netdev, &txreq, rc);
continue;
}
- xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
+ xen_pv_printf(&netdev->xendev, 3,
+ "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
txreq.gref, txreq.offset, txreq.size, txreq.flags,
(txreq.flags & NETTXF_csum_blank) ? " csum_blank" : "",
(txreq.flags & NETTXF_data_validated) ? " data_validated" : "",
@@ -162,8 +164,9 @@ static void net_tx_packets(struct XenNetDev *netdev)
netdev->xendev.dom,
txreq.gref, PROT_READ);
if (page == NULL) {
- xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n",
- txreq.gref);
+ xen_pv_printf(&netdev->xendev, 0,
+ "error: tx gref dereference failed (%d)\n",
+ txreq.gref);
net_tx_error(netdev, &txreq, rc);
continue;
}
@@ -211,13 +214,14 @@ static void net_rx_response(struct XenNetDev *netdev,
resp->status = (int16_t)st;
}
- xen_be_printf(&netdev->xendev, 3, "rx response: idx %d, status %d, flags 0x%x\n",
+ xen_pv_printf(&netdev->xendev, 3,
+ "rx response: idx %d, status %d, flags 0x%x\n",
i, resp->status, resp->flags);
netdev->rx_ring.rsp_prod_pvt = ++i;
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->rx_ring, notify);
if (notify) {
- xen_be_send_notify(&netdev->xendev);
+ xen_pv_send_notify(&netdev->xendev);
}
}
@@ -242,7 +246,7 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
return 0;
}
if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
- xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
+ xen_pv_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
(unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
return -1;
}
@@ -254,7 +258,8 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
netdev->xendev.dom,
rxreq.gref, PROT_WRITE);
if (page == NULL) {
- xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
+ xen_pv_printf(&netdev->xendev, 0,
+ "error: rx gref dereference failed (%d)\n",
rxreq.gref);
net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
return -1;
@@ -328,7 +333,8 @@ static int net_connect(struct XenDevice *xendev)
rx_copy = 0;
}
if (rx_copy == 0) {
- xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n");
+ xen_pv_printf(&netdev->xendev, 0,
+ "frontend doesn't support rx-copy.\n");
return -1;
}
@@ -353,7 +359,7 @@ static int net_connect(struct XenDevice *xendev)
xen_be_bind_evtchn(&netdev->xendev);
- xen_be_printf(&netdev->xendev, 1, "ok: tx-ring-ref %d, rx-ring-ref %d, "
+ xen_pv_printf(&netdev->xendev, 1, "ok: tx-ring-ref %d, rx-ring-ref %d, "
"remote port %d, local port %d\n",
netdev->tx_ring_ref, netdev->rx_ring_ref,
netdev->xendev.remote_port, netdev->xendev.local_port);
@@ -366,7 +372,7 @@ static void net_disconnect(struct XenDevice *xendev)
{
struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
- xen_be_unbind_evtchn(&netdev->xendev);
+ xen_pv_unbind_evtchn(&netdev->xendev);
if (netdev->txs) {
xengnttab_unmap(netdev->xendev.gnttabdev, netdev->txs, 1);
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 92aa563929..1f0c3e9910 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -29,7 +29,6 @@
#include "hw/isa/isa.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/sysbus.h"
-#include "hw/boards.h"
#include "trace.h"
#include "qemu/error-report.h"
#include "qemu/config-file.h"
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index 1cc598f7e9..6ac187fa32 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -15,7 +15,6 @@
#include "hw/pci/pci.h"
#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_host.h"
-#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_bridge.h"
#include "hw/i386/pc.h"
#include "qemu/range.h"
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 4b2f07aecb..d01798f245 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -37,7 +37,6 @@
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "hw/loader.h"
-#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "exec/address-spaces.h"
diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c
index 8e16f651ea..cf958a9e00 100644
--- a/hw/ppc/ppce500_spin.c
+++ b/hw/ppc/ppce500_spin.c
@@ -84,11 +84,11 @@ static void mmubooke_create_initial_mapping(CPUPPCState *env,
env->tlb_dirty = true;
}
-static void spin_kick(CPUState *cs, void *data)
+static void spin_kick(CPUState *cs, run_on_cpu_data data)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
- SpinInfo *curspin = data;
+ SpinInfo *curspin = data.host_ptr;
hwaddr map_size = 64 * 1024 * 1024;
hwaddr map_start;
@@ -147,7 +147,7 @@ static void spin_write(void *opaque, hwaddr addr, uint64_t value,
if (!(ldq_p(&curspin->addr) & 1)) {
/* run CPU */
- run_on_cpu(cpu, spin_kick, curspin);
+ run_on_cpu(cpu, spin_kick, RUN_ON_CPU_HOST_PTR(curspin));
}
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index c8e29212cb..0cbab24c91 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -37,7 +37,6 @@
#include "sysemu/block-backend.h"
#include "sysemu/cpus.h"
#include "sysemu/kvm.h"
-#include "sysemu/device_tree.h"
#include "kvm_ppc.h"
#include "migration/migration.h"
#include "mmu-hash64.h"
@@ -2187,7 +2186,7 @@ static void spapr_machine_finalizefn(Object *obj)
g_free(spapr->kvm_type);
}
-static void ppc_cpu_do_nmi_on_cpu(CPUState *cs, void *arg)
+static void ppc_cpu_do_nmi_on_cpu(CPUState *cs, run_on_cpu_data arg)
{
cpu_synchronize_state(cs);
ppc_cpu_do_system_reset(cs);
@@ -2198,7 +2197,7 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
CPUState *cs;
CPU_FOREACH(cs) {
- async_run_on_cpu(cs, ppc_cpu_do_nmi_on_cpu, NULL);
+ async_run_on_cpu(cs, ppc_cpu_do_nmi_on_cpu, RUN_ON_CPU_NULL);
}
}
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 7c46d4625b..9a9bedf1bd 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -19,9 +19,9 @@ struct SPRSyncState {
target_ulong mask;
};
-static void do_spr_sync(CPUState *cs, void *arg)
+static void do_spr_sync(CPUState *cs, run_on_cpu_data arg)
{
- struct SPRSyncState *s = arg;
+ struct SPRSyncState *s = arg.host_ptr;
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
@@ -38,7 +38,7 @@ static void set_spr(CPUState *cs, int spr, target_ulong value,
.value = value,
.mask = mask
};
- run_on_cpu(cs, do_spr_sync, &s);
+ run_on_cpu(cs, do_spr_sync, RUN_ON_CPU_HOST_PTR(&s));
}
static bool has_spr(PowerPCCPU *cpu, int spr)
@@ -886,10 +886,10 @@ typedef struct {
Error *err;
} SetCompatState;
-static void do_set_compat(CPUState *cs, void *arg)
+static void do_set_compat(CPUState *cs, run_on_cpu_data arg)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
- SetCompatState *s = arg;
+ SetCompatState *s = arg.host_ptr;
cpu_synchronize_state(cs);
ppc_set_compat(cpu, s->cpu_version, &s->err);
@@ -990,7 +990,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
.err = NULL,
};
- run_on_cpu(cs, do_set_compat, &s);
+ run_on_cpu(cs, do_set_compat, RUN_ON_CPU_HOST_PTR(&s));
if (s.err) {
error_report_err(s.err);
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index b7f8bca1fd..63f6248f1d 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -463,7 +463,6 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
{
S390PCIBusDevice *pbdev = opaque;
- uint32_t io_int_word;
uint32_t idx = data >> ZPCI_MSI_VEC_BITS;
uint32_t vec = data & ZPCI_MSI_VEC_MASK;
uint64_t ind_bit;
@@ -489,8 +488,7 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
0x80 >> ((ind_bit + vec) % 8));
if (!set_ind_atomic(pbdev->routes.adapter.summary_addr + sum_bit / 8,
0x80 >> (sum_bit % 8))) {
- io_int_word = (pbdev->isc << 27) | IO_INT_WORD_AI;
- s390_io_interrupt(0, 0, 0, io_int_word);
+ css_adapter_interrupt(pbdev->isc);
}
}
@@ -809,17 +807,11 @@ static uint32_t s390_pci_generate_fid(Error **errp)
{
uint32_t fid = 0;
- while (fid <= ZPCI_MAX_FID) {
+ do {
if (!s390_pci_find_dev_by_fid(fid)) {
return fid;
}
-
- if (fid == ZPCI_MAX_FID) {
- break;
- }
-
- fid++;
- }
+ } while (fid++ != ZPCI_MAX_FID);
error_setg(errp, "no free fid could be found");
return 0;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 80a51049ca..0864d9be12 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -316,6 +316,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
uint64_t offset;
uint64_t data;
MemoryRegion *mr;
+ MemTxResult result;
uint8_t len;
uint32_t fh;
uint8_t pcias;
@@ -365,8 +366,12 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
return 0;
}
mr = pbdev->pdev->io_regions[pcias].memory;
- memory_region_dispatch_read(mr, offset, &data, len,
- MEMTXATTRS_UNSPECIFIED);
+ result = memory_region_dispatch_read(mr, offset, &data, len,
+ MEMTXATTRS_UNSPECIFIED);
+ if (result != MEMTX_OK) {
+ program_interrupt(env, PGM_OPERAND, 4);
+ return 0;
+ }
} else if (pcias == 15) {
if ((4 - (offset & 0x3)) < len) {
program_interrupt(env, PGM_OPERAND, 4);
@@ -444,6 +449,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
uint64_t offset, data;
S390PCIBusDevice *pbdev;
MemoryRegion *mr;
+ MemTxResult result;
uint8_t len;
uint32_t fh;
uint8_t pcias;
@@ -502,8 +508,12 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
mr = pbdev->pdev->io_regions[pcias].memory;
}
- memory_region_dispatch_write(mr, offset, data, len,
+ result = memory_region_dispatch_write(mr, offset, data, len,
MEMTXATTRS_UNSPECIFIED);
+ if (result != MEMTX_OK) {
+ program_interrupt(env, PGM_OPERAND, 4);
+ return 0;
+ }
} else if (pcias == 15) {
if ((4 - (offset & 0x3)) < len) {
program_interrupt(env, PGM_OPERAND, 4);
@@ -633,6 +643,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
CPUS390XState *env = &cpu->env;
S390PCIBusDevice *pbdev;
MemoryRegion *mr;
+ MemTxResult result;
int i;
uint32_t fh;
uint8_t pcias;
@@ -690,7 +701,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
mr = pbdev->pdev->io_regions[pcias].memory;
if (!memory_region_access_valid(mr, env->regs[r3], len, true)) {
- program_interrupt(env, PGM_ADDRESSING, 6);
+ program_interrupt(env, PGM_OPERAND, 6);
return 0;
}
@@ -699,9 +710,13 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
}
for (i = 0; i < len / 8; i++) {
- memory_region_dispatch_write(mr, env->regs[r3] + i * 8,
+ result = memory_region_dispatch_write(mr, env->regs[r3] + i * 8,
ldq_p(buffer + i * 8), 8,
MEMTXATTRS_UNSPECIFIED);
+ if (result != MEMTX_OK) {
+ program_interrupt(env, PGM_OPERAND, 6);
+ return 0;
+ }
}
setcc(cpu, ZPCI_PCI_LS_OK);
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index aa6be541ec..f2ea29dbc3 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -201,13 +201,11 @@ void virtio_scsi_dataplane_stop(VirtIODevice *vdev)
s->dataplane_stopping = true;
aio_context_acquire(s->ctx);
-
virtio_scsi_clear_aio(s);
+ aio_context_release(s->ctx);
blk_drain_all(); /* ensure there are no in-flight requests */
- aio_context_release(s->ctx);
-
for (i = 0; i < vs->conf.num_queues + 2; i++) {
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
}
diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c
index 712d1aece5..4ed96e970a 100644
--- a/hw/timer/grlib_gptimer.c
+++ b/hw/timer/grlib_gptimer.c
@@ -26,7 +26,6 @@
#include "hw/sysbus.h"
#include "qemu/timer.h"
#include "hw/ptimer.h"
-#include "qemu/timer.h"
#include "qemu/main-loop.h"
#include "trace.h"
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index e88c0d20bc..9234eb3459 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -165,8 +165,7 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
ret = tpm_passthrough_unix_write(tpm_pt->tpm_fd, in, in_len);
if (ret != in_len) {
- if (!tpm_pt->tpm_op_canceled ||
- (tpm_pt->tpm_op_canceled && errno != ECANCELED)) {
+ if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
error_report("tpm_passthrough: error while transmitting data "
"to TPM: %s (%i)",
strerror(errno), errno);
@@ -178,8 +177,7 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
ret = tpm_passthrough_unix_read(tpm_pt->tpm_fd, out, out_len);
if (ret < 0) {
- if (!tpm_pt->tpm_op_canceled ||
- (tpm_pt->tpm_op_canceled && errno != ECANCELED)) {
+ if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
error_report("tpm_passthrough: error while reading data from "
"TPM: %s (%i)",
strerror(errno), errno);
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 381e7266ea..a6440fef91 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -34,7 +34,6 @@
#include "qapi/error.h"
#include "qemu-common.h"
#include "qemu/main-loop.h"
-#include "sysemu/tpm_backend.h"
#define DEBUG_TIS 0
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index 31cd171016..032078fd3e 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -13,7 +13,6 @@
#include "qapi/error.h"
#include "qemu-common.h"
#include "cpu.h"
-#include "qemu-common.h"
#include "ui/console.h"
#include "elf.h"
#include "exec/address-spaces.h"
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index 3213f9f8af..eceb5f3ee2 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -547,7 +547,7 @@ static int emulated_initfn(CCIDCardState *base)
return 0;
}
-static int emulated_exitfn(CCIDCardState *base)
+static void emulated_exitfn(CCIDCardState *base)
{
EmulatedState *card = EMULATED_CCID_CARD(base);
VEvent *vevent = vevent_new(VEVENT_LAST, NULL, NULL);
@@ -564,7 +564,6 @@ static int emulated_exitfn(CCIDCardState *base)
qemu_mutex_destroy(&card->handle_apdu_mutex);
qemu_mutex_destroy(&card->vreader_mutex);
qemu_mutex_destroy(&card->event_list_mutex);
- return 0;
}
static Property emulated_card_properties[] = {
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index 325129a2f6..88cb6d8978 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -365,11 +365,6 @@ static int passthru_initfn(CCIDCardState *base)
return 0;
}
-static int passthru_exitfn(CCIDCardState *base)
-{
- return 0;
-}
-
static VMStateDescription passthru_vmstate = {
.name = "ccid-card-passthru",
.version_id = 1,
@@ -396,7 +391,6 @@ static void passthru_class_initfn(ObjectClass *klass, void *data)
CCIDCardClass *cc = CCID_CARD_CLASS(klass);
cc->initfn = passthru_initfn;
- cc->exitfn = passthru_exitfn;
cc->get_atr = passthru_get_atr;
cc->apdu_from_guest = passthru_apdu_from_guest;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
diff --git a/hw/usb/ccid.h b/hw/usb/ccid.h
index 9334da8acd..1f070116d6 100644
--- a/hw/usb/ccid.h
+++ b/hw/usb/ccid.h
@@ -33,7 +33,7 @@ typedef struct CCIDCardClass {
void (*apdu_from_guest)(CCIDCardState *card,
const uint8_t *apdu,
uint32_t len);
- int (*exitfn)(CCIDCardState *card);
+ void (*exitfn)(CCIDCardState *card);
int (*initfn)(CCIDCardState *card);
} CCIDCardClass;
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 58d95fffb2..9cb0f50750 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -17,7 +17,6 @@
#include <sys/statvfs.h>
#ifdef CONFIG_INOTIFY1
#include <sys/inotify.h>
-#include "qapi/error.h"
#include "qemu/main-loop.h"
#endif
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index af4b851356..89e11b68c4 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -508,14 +508,14 @@ static void ccid_card_apdu_from_guest(CCIDCardState *card,
}
}
-static int ccid_card_exitfn(CCIDCardState *card)
+static void ccid_card_exitfn(CCIDCardState *card)
{
CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
if (cc->exitfn) {
- return cc->exitfn(card);
+ cc->exitfn(card);
}
- return 0;
+
}
static int ccid_card_initfn(CCIDCardState *card)
@@ -1279,7 +1279,6 @@ void ccid_card_card_inserted(CCIDCardState *card)
static int ccid_card_exit(DeviceState *qdev)
{
- int ret = 0;
CCIDCardState *card = CCID_CARD(qdev);
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
@@ -1287,9 +1286,9 @@ static int ccid_card_exit(DeviceState *qdev)
if (ccid_card_inserted(s)) {
ccid_card_card_removed(card);
}
- ret = ccid_card_exitfn(card);
+ ccid_card_exitfn(card);
s->card = NULL;
- return ret;
+ return 0;
}
static int ccid_card_init(DeviceState *qdev)
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
index de2ebd6210..1b3c2fb3c7 100644
--- a/hw/usb/xen-usb.c
+++ b/hw/usb/xen-usb.c
@@ -47,7 +47,7 @@
struct timeval tv; \
\
gettimeofday(&tv, NULL); \
- xen_be_printf(xendev, lvl, "%8ld.%06ld xen-usb(%s):" fmt, \
+ xen_pv_printf(xendev, lvl, "%8ld.%06ld xen-usb(%s):" fmt, \
tv.tv_sec, tv.tv_usec, __func__, ##args); \
}
#define TR_BUS(xendev, fmt, args...) TR(xendev, 2, fmt, ##args)
@@ -153,7 +153,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
}
if (nr_segs > USBIF_MAX_SEGMENTS_PER_REQUEST) {
- xen_be_printf(xendev, 0, "bad number of segments in request (%d)\n",
+ xen_pv_printf(xendev, 0, "bad number of segments in request (%d)\n",
nr_segs);
return -EINVAL;
}
@@ -161,7 +161,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
for (i = 0; i < nr_segs; i++) {
if ((unsigned)usbback_req->req.seg[i].offset +
(unsigned)usbback_req->req.seg[i].length > XC_PAGE_SIZE) {
- xen_be_printf(xendev, 0, "segment crosses page boundary\n");
+ xen_pv_printf(xendev, 0, "segment crosses page boundary\n");
return -EINVAL;
}
}
@@ -199,7 +199,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
*/
if (!usbback_req->nr_extra_segs) {
- xen_be_printf(xendev, 0, "iso request without descriptor segments\n");
+ xen_pv_printf(xendev, 0, "iso request without descriptor segments\n");
return -EINVAL;
}
@@ -314,7 +314,7 @@ static void usbback_do_response(struct usbback_req *usbback_req, int32_t status,
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif->urb_ring, notify);
if (notify) {
- xen_be_send_notify(xendev);
+ xen_pv_send_notify(xendev);
}
}
@@ -551,14 +551,14 @@ static void usbback_dispatch(struct usbback_req *usbback_req)
ret = usbback_init_packet(usbback_req);
if (ret) {
- xen_be_printf(&usbif->xendev, 0, "invalid request\n");
+ xen_pv_printf(&usbif->xendev, 0, "invalid request\n");
ret = -ESHUTDOWN;
goto fail_free_urb;
}
ret = usbback_gnttab_map(usbback_req);
if (ret) {
- xen_be_printf(&usbif->xendev, 0, "invalid buffer, ret=%d\n", ret);
+ xen_pv_printf(&usbif->xendev, 0, "invalid buffer, ret=%d\n", ret);
ret = -ESHUTDOWN;
goto fail_free_urb;
}
@@ -590,7 +590,7 @@ static void usbback_hotplug_notify(struct usbback_info *usbif)
/* Check for full ring. */
if ((RING_SIZE(ring) - ring->rsp_prod_pvt - ring->req_cons) == 0) {
- xen_be_send_notify(&usbif->xendev);
+ xen_pv_send_notify(&usbif->xendev);
return;
}
@@ -609,7 +609,7 @@ static void usbback_hotplug_notify(struct usbback_info *usbif)
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(ring, notify);
if (notify) {
- xen_be_send_notify(&usbif->xendev);
+ xen_pv_send_notify(&usbif->xendev);
}
TR_BUS(&usbif->xendev, "hotplug port %d speed %d\n", usb_hp->port,
@@ -646,7 +646,7 @@ static void usbback_bh(void *opaque)
if (RING_REQUEST_PROD_OVERFLOW(urb_ring, rp)) {
rc = urb_ring->rsp_prod_pvt;
- xen_be_printf(&usbif->xendev, 0, "domU provided bogus ring requests "
+ xen_pv_printf(&usbif->xendev, 0, "domU provided bogus ring requests "
"(%#x - %#x = %u). Halting ring processing.\n",
rp, rc, rp - rc);
usbif->ring_error = true;
@@ -744,7 +744,7 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
portname = strchr(busid, '-');
if (!portname) {
- xen_be_printf(&usbif->xendev, 0, "device %s illegal specification\n",
+ xen_pv_printf(&usbif->xendev, 0, "device %s illegal specification\n",
busid);
return;
}
@@ -783,7 +783,7 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
break;
}
if (speed == USBIF_SPEED_NONE) {
- xen_be_printf(&usbif->xendev, 0, "device %s wrong speed\n", busid);
+ xen_pv_printf(&usbif->xendev, 0, "device %s wrong speed\n", busid);
object_unparent(OBJECT(usbif->ports[port - 1].dev));
usbif->ports[port - 1].dev = NULL;
return;
@@ -800,7 +800,7 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
err:
QDECREF(qdict);
snprintf(p->path, sizeof(p->path), "%d", 99);
- xen_be_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);
}
static void usbback_process_port(struct usbback_info *usbif, unsigned port)
@@ -811,7 +811,7 @@ static void usbback_process_port(struct usbback_info *usbif, unsigned port)
snprintf(node, sizeof(node), "port/%d", port);
busid = xenstore_read_be_str(&usbif->xendev, node);
if (busid == NULL) {
- xen_be_printf(&usbif->xendev, 0, "xenstore_read %s failed\n", node);
+ xen_pv_printf(&usbif->xendev, 0, "xenstore_read %s failed\n", node);
return;
}
@@ -834,7 +834,7 @@ static void usbback_disconnect(struct XenDevice *xendev)
usbif = container_of(xendev, struct usbback_info, xendev);
- xen_be_unbind_evtchn(xendev);
+ xen_pv_unbind_evtchn(xendev);
if (usbif->urb_sring) {
xengnttab_unmap(xendev->gnttabdev, usbif->urb_sring, 1);
@@ -868,15 +868,15 @@ static int usbback_connect(struct XenDevice *xendev)
usbif = container_of(xendev, struct usbback_info, xendev);
if (xenstore_read_fe_int(xendev, "urb-ring-ref", &urb_ring_ref)) {
- xen_be_printf(xendev, 0, "error reading urb-ring-ref\n");
+ xen_pv_printf(xendev, 0, "error reading urb-ring-ref\n");
return -1;
}
if (xenstore_read_fe_int(xendev, "conn-ring-ref", &conn_ring_ref)) {
- xen_be_printf(xendev, 0, "error reading conn-ring-ref\n");
+ xen_pv_printf(xendev, 0, "error reading conn-ring-ref\n");
return -1;
}
if (xenstore_read_fe_int(xendev, "event-channel", &xendev->remote_port)) {
- xen_be_printf(xendev, 0, "error reading event-channel\n");
+ xen_pv_printf(xendev, 0, "error reading event-channel\n");
return -1;
}
@@ -887,7 +887,7 @@ static int usbback_connect(struct XenDevice *xendev)
conn_ring_ref,
PROT_READ | PROT_WRITE);
if (!usbif->urb_sring || !usbif->conn_sring) {
- xen_be_printf(xendev, 0, "error mapping rings\n");
+ xen_pv_printf(xendev, 0, "error mapping rings\n");
usbback_disconnect(xendev);
return -1;
}
@@ -899,7 +899,7 @@ static int usbback_connect(struct XenDevice *xendev)
xen_be_bind_evtchn(xendev);
- xen_be_printf(xendev, 1, "urb-ring-ref %d, conn-ring-ref %d, "
+ xen_pv_printf(xendev, 1, "urb-ring-ref %d, conn-ring-ref %d, "
"remote port %d, local port %d\n", urb_ring_ref,
conn_ring_ref, xendev->remote_port, xendev->local_port);
@@ -935,12 +935,12 @@ static int usbback_init(struct XenDevice *xendev)
if (xenstore_read_be_int(xendev, "num-ports", &usbif->num_ports) ||
usbif->num_ports < 1 || usbif->num_ports > USBBACK_MAXPORTS) {
- xen_be_printf(xendev, 0, "num-ports not readable or out of bounds\n");
+ xen_pv_printf(xendev, 0, "num-ports not readable or out of bounds\n");
return -1;
}
if (xenstore_read_be_int(xendev, "usb-ver", &usbif->usb_ver) ||
(usbif->usb_ver != USB_VER_USB11 && usbif->usb_ver != USB_VER_USB20)) {
- xen_be_printf(xendev, 0, "usb-ver not readable or out of bounds\n");
+ xen_pv_printf(xendev, 0, "usb-ver not readable or out of bounds\n");
return -1;
}
@@ -1028,7 +1028,7 @@ static void usbback_alloc(struct XenDevice *xendev)
/* max_grants: for each request and for the rings (request and connect). */
max_grants = USBIF_MAX_SEGMENTS_PER_REQUEST * USB_URB_RING_SIZE + 2;
if (xengnttab_set_max_grants(xendev->gnttabdev, max_grants) < 0) {
- xen_be_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
+ xen_pv_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
strerror(errno));
}
}
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 9505fb3040..801578b4b9 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -610,16 +610,16 @@ vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id)
return NULL;
}
-static void vfio_setup_region_sparse_mmaps(VFIORegion *region,
- struct vfio_region_info *info)
+static int vfio_setup_region_sparse_mmaps(VFIORegion *region,
+ struct vfio_region_info *info)
{
struct vfio_info_cap_header *hdr;
struct vfio_region_info_cap_sparse_mmap *sparse;
- int i;
+ int i, j;
hdr = vfio_get_region_info_cap(info, VFIO_REGION_INFO_CAP_SPARSE_MMAP);
if (!hdr) {
- return;
+ return -ENODEV;
}
sparse = container_of(hdr, struct vfio_region_info_cap_sparse_mmap, header);
@@ -627,16 +627,24 @@ static void vfio_setup_region_sparse_mmaps(VFIORegion *region,
trace_vfio_region_sparse_mmap_header(region->vbasedev->name,
region->nr, sparse->nr_areas);
- region->nr_mmaps = sparse->nr_areas;
- region->mmaps = g_new0(VFIOMmap, region->nr_mmaps);
+ region->mmaps = g_new0(VFIOMmap, sparse->nr_areas);
- for (i = 0; i < region->nr_mmaps; i++) {
- region->mmaps[i].offset = sparse->areas[i].offset;
- region->mmaps[i].size = sparse->areas[i].size;
- trace_vfio_region_sparse_mmap_entry(i, region->mmaps[i].offset,
- region->mmaps[i].offset +
- region->mmaps[i].size);
+ for (i = 0, j = 0; i < sparse->nr_areas; i++) {
+ trace_vfio_region_sparse_mmap_entry(i, sparse->areas[i].offset,
+ sparse->areas[i].offset +
+ sparse->areas[i].size);
+
+ if (sparse->areas[i].size) {
+ region->mmaps[j].offset = sparse->areas[i].offset;
+ region->mmaps[j].size = sparse->areas[i].size;
+ j++;
+ }
}
+
+ region->nr_mmaps = j;
+ region->mmaps = g_realloc(region->mmaps, j * sizeof(VFIOMmap));
+
+ return 0;
}
int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region,
@@ -662,12 +670,11 @@ int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region,
region, name, region->size);
if (!vbasedev->no_mmap &&
- region->flags & VFIO_REGION_INFO_FLAG_MMAP &&
- !(region->size & ~qemu_real_host_page_mask)) {
+ region->flags & VFIO_REGION_INFO_FLAG_MMAP) {
- vfio_setup_region_sparse_mmaps(region, info);
+ ret = vfio_setup_region_sparse_mmaps(region, info);
- if (!region->nr_mmaps) {
+ if (ret) {
region->nr_mmaps = 1;
region->mmaps = g_new0(VFIOMmap, region->nr_mmaps);
region->mmaps[0].offset = 0;
@@ -724,12 +731,11 @@ int vfio_region_mmap(VFIORegion *region)
name = g_strdup_printf("%s mmaps[%d]",
memory_region_name(region->mem), i);
- memory_region_init_ram_ptr(&region->mmaps[i].mem,
- memory_region_owner(region->mem),
- name, region->mmaps[i].size,
- region->mmaps[i].mmap);
+ memory_region_init_ram_device_ptr(&region->mmaps[i].mem,
+ memory_region_owner(region->mem),
+ name, region->mmaps[i].size,
+ region->mmaps[i].mmap);
g_free(name);
- memory_region_set_skip_dump(&region->mmaps[i].mem);
memory_region_add_subregion(region->mem, region->mmaps[i].offset,
&region->mmaps[i].mem);
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 65d30fdef9..d7dbe0e3e0 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1071,6 +1071,55 @@ static const MemoryRegionOps vfio_vga_ops = {
};
/*
+ * Expand memory region of sub-page(size < PAGE_SIZE) MMIO BAR to page
+ * size if the BAR is in an exclusive page in host so that we could map
+ * this BAR to guest. But this sub-page BAR may not occupy an exclusive
+ * page in guest. So we should set the priority of the expanded memory
+ * region to zero in case of overlap with BARs which share the same page
+ * with the sub-page BAR in guest. Besides, we should also recover the
+ * size of this sub-page BAR when its base address is changed in guest
+ * and not page aligned any more.
+ */
+static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar)
+{
+ VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+ VFIORegion *region = &vdev->bars[bar].region;
+ MemoryRegion *mmap_mr, *mr;
+ PCIIORegion *r;
+ pcibus_t bar_addr;
+ uint64_t size = region->size;
+
+ /* Make sure that the whole region is allowed to be mmapped */
+ if (region->nr_mmaps != 1 || !region->mmaps[0].mmap ||
+ region->mmaps[0].size != region->size) {
+ return;
+ }
+
+ r = &pdev->io_regions[bar];
+ bar_addr = r->addr;
+ mr = region->mem;
+ mmap_mr = &region->mmaps[0].mem;
+
+ /* If BAR is mapped and page aligned, update to fill PAGE_SIZE */
+ if (bar_addr != PCI_BAR_UNMAPPED &&
+ !(bar_addr & ~qemu_real_host_page_mask)) {
+ size = qemu_real_host_page_size;
+ }
+
+ memory_region_transaction_begin();
+
+ memory_region_set_size(mr, size);
+ memory_region_set_size(mmap_mr, size);
+ if (size != region->size && memory_region_is_mapped(mr)) {
+ memory_region_del_subregion(r->address_space, mr);
+ memory_region_add_subregion_overlap(r->address_space,
+ bar_addr, mr, 0);
+ }
+
+ memory_region_transaction_commit();
+}
+
+/*
* PCI config space
*/
uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
@@ -1153,6 +1202,24 @@ void vfio_pci_write_config(PCIDevice *pdev,
} else if (was_enabled && !is_enabled) {
vfio_msix_disable(vdev);
}
+ } else if (ranges_overlap(addr, len, PCI_BASE_ADDRESS_0, 24) ||
+ range_covers_byte(addr, len, PCI_COMMAND)) {
+ pcibus_t old_addr[PCI_NUM_REGIONS - 1];
+ int bar;
+
+ for (bar = 0; bar < PCI_ROM_SLOT; bar++) {
+ old_addr[bar] = pdev->io_regions[bar].addr;
+ }
+
+ pci_default_write_config(pdev, addr, val, len);
+
+ for (bar = 0; bar < PCI_ROM_SLOT; bar++) {
+ if (old_addr[bar] != pdev->io_regions[bar].addr &&
+ pdev->io_regions[bar].size > 0 &&
+ pdev->io_regions[bar].size < qemu_real_host_page_size) {
+ vfio_sub_page_bar_update_mapping(pdev, bar);
+ }
+ }
} else {
/* Write everything to QEMU to keep emulated bits correct */
pci_default_write_config(pdev, addr, val, len);
@@ -1922,11 +1989,23 @@ static void vfio_pci_pre_reset(VFIOPCIDevice *vdev)
static void vfio_pci_post_reset(VFIOPCIDevice *vdev)
{
Error *err = NULL;
+ int nr;
vfio_intx_enable(vdev, &err);
if (err) {
error_reportf_err(err, ERR_PREFIX, vdev->vbasedev.name);
}
+
+ for (nr = 0; nr < PCI_NUM_REGIONS - 1; ++nr) {
+ off_t addr = vdev->config_offset + PCI_BASE_ADDRESS_0 + (4 * nr);
+ uint32_t val = 0;
+ uint32_t len = sizeof(val);
+
+ if (pwrite(vdev->vbasedev.fd, &val, len, addr) != len) {
+ error_report("%s(%s) reset bar %d failed: %m", __func__,
+ vdev->vbasedev.name, nr);
+ }
+ }
}
static bool vfio_pci_host_match(PCIHostDeviceAddress *addr, const char *name)
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
index 7443d348d9..4409bcc0d7 100644
--- a/hw/vfio/spapr.c
+++ b/hw/vfio/spapr.c
@@ -25,7 +25,7 @@ static bool vfio_prereg_listener_skipped_section(MemoryRegionSection *section)
}
return !memory_region_is_ram(section->mr) ||
- memory_region_is_skip_dump(section->mr);
+ memory_region_is_ram_device(section->mr);
}
static void *vfio_prereg_gpa_to_vaddr(MemoryRegionSection *section, hwaddr gpa)
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index d3670940b7..591cdc229d 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
# xen backend driver support
-common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o
+common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o xen_pvdev.o
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index 69a238817e..41ba5c585a 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -30,6 +30,7 @@
#include "sysemu/char.h"
#include "qemu/log.h"
#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen_pvdev.h"
#include <xen/grant_table.h>
@@ -46,129 +47,7 @@ struct xs_handle *xenstore = NULL;
const char *xen_protocol;
/* private */
-struct xs_dirs {
- char *xs_dir;
- QTAILQ_ENTRY(xs_dirs) list;
-};
-static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
- QTAILQ_HEAD_INITIALIZER(xs_cleanup);
-
-static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs);
-static int debug = 0;
-
-/* ------------------------------------------------------------- */
-
-static void xenstore_cleanup_dir(char *dir)
-{
- struct xs_dirs *d;
-
- d = g_malloc(sizeof(*d));
- d->xs_dir = dir;
- QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
-}
-
-void xen_config_cleanup(void)
-{
- struct xs_dirs *d;
-
- QTAILQ_FOREACH(d, &xs_cleanup, list) {
- xs_rm(xenstore, 0, d->xs_dir);
- }
-}
-
-int xenstore_write_str(const char *base, const char *node, const char *val)
-{
- char abspath[XEN_BUFSIZE];
-
- snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
- if (!xs_write(xenstore, 0, abspath, val, strlen(val))) {
- return -1;
- }
- return 0;
-}
-
-char *xenstore_read_str(const char *base, const char *node)
-{
- char abspath[XEN_BUFSIZE];
- unsigned int len;
- char *str, *ret = NULL;
-
- snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
- str = xs_read(xenstore, 0, abspath, &len);
- if (str != NULL) {
- /* move to qemu-allocated memory to make sure
- * callers can savely g_free() stuff. */
- ret = g_strdup(str);
- free(str);
- }
- return ret;
-}
-
-int xenstore_mkdir(char *path, int p)
-{
- struct xs_permissions perms[2] = {
- {
- .id = 0, /* set owner: dom0 */
- }, {
- .id = xen_domid,
- .perms = p,
- }
- };
-
- if (!xs_mkdir(xenstore, 0, path)) {
- xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", path);
- return -1;
- }
- xenstore_cleanup_dir(g_strdup(path));
-
- if (!xs_set_permissions(xenstore, 0, path, perms, 2)) {
- xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", path);
- return -1;
- }
- return 0;
-}
-
-int xenstore_write_int(const char *base, const char *node, int ival)
-{
- char val[12];
-
- snprintf(val, sizeof(val), "%d", ival);
- return xenstore_write_str(base, node, val);
-}
-
-int xenstore_write_int64(const char *base, const char *node, int64_t ival)
-{
- char val[21];
-
- snprintf(val, sizeof(val), "%"PRId64, ival);
- return xenstore_write_str(base, node, val);
-}
-
-int xenstore_read_int(const char *base, const char *node, int *ival)
-{
- char *val;
- int rc = -1;
-
- val = xenstore_read_str(base, node);
- if (val && 1 == sscanf(val, "%d", ival)) {
- rc = 0;
- }
- g_free(val);
- return rc;
-}
-
-int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval)
-{
- char *val;
- int rc = -1;
-
- val = xenstore_read_str(base, node);
- if (val && 1 == sscanf(val, "%"SCNu64, uval)) {
- rc = 0;
- }
- g_free(val);
- return rc;
-}
+static int debug;
int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val)
{
@@ -205,27 +84,14 @@ int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
return xenstore_read_int(xendev->fe, node, ival);
}
-int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node, uint64_t *uval)
+int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
+ uint64_t *uval)
{
return xenstore_read_uint64(xendev->fe, node, uval);
}
/* ------------------------------------------------------------- */
-const char *xenbus_strstate(enum xenbus_state state)
-{
- static const char *const name[] = {
- [ XenbusStateUnknown ] = "Unknown",
- [ XenbusStateInitialising ] = "Initialising",
- [ XenbusStateInitWait ] = "InitWait",
- [ XenbusStateInitialised ] = "Initialised",
- [ XenbusStateConnected ] = "Connected",
- [ XenbusStateClosing ] = "Closing",
- [ XenbusStateClosed ] = "Closed",
- };
- return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
-}
-
int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
{
int rc;
@@ -234,33 +100,12 @@ int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
if (rc < 0) {
return rc;
}
- xen_be_printf(xendev, 1, "backend state: %s -> %s\n",
+ xen_pv_printf(xendev, 1, "backend state: %s -> %s\n",
xenbus_strstate(xendev->be_state), xenbus_strstate(state));
xendev->be_state = state;
return 0;
}
-/* ------------------------------------------------------------- */
-
-struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev)
-{
- struct XenDevice *xendev;
-
- QTAILQ_FOREACH(xendev, &xendevs, next) {
- if (xendev->dom != dom) {
- continue;
- }
- if (xendev->dev != dev) {
- continue;
- }
- if (strcmp(xendev->type, type) != 0) {
- continue;
- }
- return xendev;
- }
- return NULL;
-}
-
/*
* get xen backend device, allocate a new one if it doesn't exist.
*/
@@ -269,7 +114,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
{
struct XenDevice *xendev;
- xendev = xen_be_find_xendev(type, dom, dev);
+ xendev = xen_pv_find_xendev(type, dom, dev);
if (xendev) {
return xendev;
}
@@ -291,7 +136,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
xendev->evtchndev = xenevtchn_open(NULL, 0);
if (xendev->evtchndev == NULL) {
- xen_be_printf(NULL, 0, "can't open evtchn device\n");
+ xen_pv_printf(NULL, 0, "can't open evtchn device\n");
g_free(xendev);
return NULL;
}
@@ -300,7 +145,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
xendev->gnttabdev = xengnttab_open(NULL, 0);
if (xendev->gnttabdev == NULL) {
- xen_be_printf(NULL, 0, "can't open gnttab device\n");
+ xen_pv_printf(NULL, 0, "can't open gnttab device\n");
xenevtchn_close(xendev->evtchndev);
g_free(xendev);
return NULL;
@@ -309,7 +154,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
xendev->gnttabdev = NULL;
}
- QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
+ xen_pv_insert_xendev(xendev);
if (xendev->ops->alloc) {
xendev->ops->alloc(xendev);
@@ -318,32 +163,6 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
return xendev;
}
-/*
- * release xen backend device.
- */
-static void xen_be_del_xendev(struct XenDevice *xendev)
-{
- if (xendev->ops->free) {
- xendev->ops->free(xendev);
- }
-
- if (xendev->fe) {
- char token[XEN_BUFSIZE];
- snprintf(token, sizeof(token), "fe:%p", xendev);
- xs_unwatch(xenstore, xendev->fe, token);
- g_free(xendev->fe);
- }
-
- if (xendev->evtchndev != NULL) {
- xenevtchn_close(xendev->evtchndev);
- }
- if (xendev->gnttabdev != NULL) {
- xengnttab_close(xendev->gnttabdev);
- }
-
- QTAILQ_REMOVE(&xendevs, xendev, next);
- g_free(xendev);
-}
/*
* Sync internal data structures on xenstore updates.
@@ -359,7 +178,7 @@ static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
}
if (node) {
- xen_be_printf(xendev, 2, "backend update: %s\n", node);
+ xen_pv_printf(xendev, 2, "backend update: %s\n", node);
if (xendev->ops->backend_changed) {
xendev->ops->backend_changed(xendev, node);
}
@@ -375,7 +194,7 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
fe_state = XenbusStateUnknown;
}
if (xendev->fe_state != fe_state) {
- xen_be_printf(xendev, 1, "frontend state: %s -> %s\n",
+ xen_pv_printf(xendev, 1, "frontend state: %s -> %s\n",
xenbus_strstate(xendev->fe_state),
xenbus_strstate(fe_state));
}
@@ -385,12 +204,13 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
g_free(xendev->protocol);
xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
if (xendev->protocol) {
- xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
+ xen_pv_printf(xendev, 1, "frontend protocol: %s\n",
+ xendev->protocol);
}
}
if (node) {
- xen_be_printf(xendev, 2, "frontend update: %s\n", node);
+ xen_pv_printf(xendev, 2, "frontend update: %s\n", node);
if (xendev->ops->frontend_changed) {
xendev->ops->frontend_changed(xendev, node);
}
@@ -414,26 +234,26 @@ static int xen_be_try_setup(struct XenDevice *xendev)
int be_state;
if (xenstore_read_be_int(xendev, "state", &be_state) == -1) {
- xen_be_printf(xendev, 0, "reading backend state failed\n");
+ xen_pv_printf(xendev, 0, "reading backend state failed\n");
return -1;
}
if (be_state != XenbusStateInitialising) {
- xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
+ xen_pv_printf(xendev, 0, "initial backend state is wrong (%s)\n",
xenbus_strstate(be_state));
return -1;
}
xendev->fe = xenstore_read_be_str(xendev, "frontend");
if (xendev->fe == NULL) {
- xen_be_printf(xendev, 0, "reading frontend path failed\n");
+ xen_pv_printf(xendev, 0, "reading frontend path failed\n");
return -1;
}
/* setup frontend watch */
snprintf(token, sizeof(token), "fe:%p", xendev);
if (!xs_watch(xenstore, xendev->fe, token)) {
- xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
+ xen_pv_printf(xendev, 0, "watching frontend path (%s) failed\n",
xendev->fe);
return -1;
}
@@ -457,7 +277,7 @@ static int xen_be_try_init(struct XenDevice *xendev)
int rc = 0;
if (!xendev->online) {
- xen_be_printf(xendev, 1, "not online\n");
+ xen_pv_printf(xendev, 1, "not online\n");
return -1;
}
@@ -465,7 +285,7 @@ static int xen_be_try_init(struct XenDevice *xendev)
rc = xendev->ops->init(xendev);
}
if (rc != 0) {
- xen_be_printf(xendev, 1, "init() failed\n");
+ xen_pv_printf(xendev, 1, "init() failed\n");
return rc;
}
@@ -488,9 +308,9 @@ static int xen_be_try_initialise(struct XenDevice *xendev)
if (xendev->fe_state != XenbusStateInitialised &&
xendev->fe_state != XenbusStateConnected) {
if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
- xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
+ xen_pv_printf(xendev, 2, "frontend not ready, ignoring\n");
} else {
- xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
+ xen_pv_printf(xendev, 2, "frontend not ready (yet)\n");
return -1;
}
}
@@ -499,7 +319,7 @@ static int xen_be_try_initialise(struct XenDevice *xendev)
rc = xendev->ops->initialise(xendev);
}
if (rc != 0) {
- xen_be_printf(xendev, 0, "initialise() failed\n");
+ xen_pv_printf(xendev, 0, "initialise() failed\n");
return rc;
}
@@ -520,9 +340,9 @@ static void xen_be_try_connected(struct XenDevice *xendev)
if (xendev->fe_state != XenbusStateConnected) {
if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
- xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
+ xen_pv_printf(xendev, 2, "frontend not ready, ignoring\n");
} else {
- xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
+ xen_pv_printf(xendev, 2, "frontend not ready (yet)\n");
return;
}
}
@@ -556,7 +376,7 @@ static int xen_be_try_reset(struct XenDevice *xendev)
return -1;
}
- xen_be_printf(xendev, 1, "device reset (for re-connect)\n");
+ xen_pv_printf(xendev, 1, "device reset (for re-connect)\n");
xen_be_set_state(xendev, XenbusStateInitialising);
return 0;
}
@@ -617,7 +437,8 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops);
snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
if (!xs_watch(xenstore, path, token)) {
- xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", path);
+ xen_pv_printf(NULL, 0, "xen be: watching backend path (%s) failed\n",
+ path);
return -1;
}
@@ -637,8 +458,8 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
return 0;
}
-static void xenstore_update_be(char *watch, char *type, int dom,
- struct XenDevOps *ops)
+void xenstore_update_be(char *watch, char *type, int dom,
+ struct XenDevOps *ops)
{
struct XenDevice *xendev;
char path[XEN_BUFSIZE], *bepath;
@@ -662,7 +483,7 @@ static void xenstore_update_be(char *watch, char *type, int dom,
if (xendev != NULL) {
bepath = xs_read(xenstore, 0, xendev->be, &len);
if (bepath == NULL) {
- xen_be_del_xendev(xendev);
+ xen_pv_del_xendev(xendev);
} else {
free(bepath);
xen_be_backend_changed(xendev, path);
@@ -671,7 +492,7 @@ static void xenstore_update_be(char *watch, char *type, int dom,
}
}
-static void xenstore_update_fe(char *watch, struct XenDevice *xendev)
+void xenstore_update_fe(char *watch, struct XenDevice *xendev)
{
char *node;
unsigned int len;
@@ -688,56 +509,13 @@ static void xenstore_update_fe(char *watch, struct XenDevice *xendev)
xen_be_frontend_changed(xendev, node);
xen_be_check_state(xendev);
}
-
-static void xenstore_update(void *unused)
-{
- char **vec = NULL;
- intptr_t type, ops, ptr;
- unsigned int dom, count;
-
- vec = xs_read_watch(xenstore, &count);
- if (vec == NULL) {
- goto cleanup;
- }
-
- if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR,
- &type, &dom, &ops) == 3) {
- xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
- }
- if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) {
- xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
- }
-
-cleanup:
- free(vec);
-}
-
-static void xen_be_evtchn_event(void *opaque)
-{
- struct XenDevice *xendev = opaque;
- evtchn_port_t port;
-
- port = xenevtchn_pending(xendev->evtchndev);
- if (port != xendev->local_port) {
- xen_be_printf(xendev, 0,
- "xenevtchn_pending returned %d (expected %d)\n",
- port, xendev->local_port);
- return;
- }
- xenevtchn_unmask(xendev->evtchndev, port);
-
- if (xendev->ops->event) {
- xendev->ops->event(xendev);
- }
-}
-
/* -------------------------------------------------------------------- */
int xen_be_init(void)
{
xenstore = xs_daemon_open();
if (!xenstore) {
- xen_be_printf(NULL, 0, "can't connect to xenstored\n");
+ xen_pv_printf(NULL, 0, "can't connect to xenstored\n");
return -1;
}
@@ -798,69 +576,15 @@ int xen_be_bind_evtchn(struct XenDevice *xendev)
xendev->local_port = xenevtchn_bind_interdomain
(xendev->evtchndev, xendev->dom, xendev->remote_port);
if (xendev->local_port == -1) {
- xen_be_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n");
+ xen_pv_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n");
return -1;
}
- xen_be_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
+ xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev),
- xen_be_evtchn_event, NULL, xendev);
+ xen_pv_evtchn_event, NULL, xendev);
return 0;
}
-void xen_be_unbind_evtchn(struct XenDevice *xendev)
-{
- if (xendev->local_port == -1) {
- return;
- }
- qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
- xenevtchn_unbind(xendev->evtchndev, xendev->local_port);
- xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
- xendev->local_port = -1;
-}
-
-int xen_be_send_notify(struct XenDevice *xendev)
-{
- return xenevtchn_notify(xendev->evtchndev, xendev->local_port);
-}
-
-/*
- * msg_level:
- * 0 == errors (stderr + logfile).
- * 1 == informative debug messages (logfile only).
- * 2 == noisy debug messages (logfile only).
- * 3 == will flood your log (logfile only).
- */
-void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...)
-{
- va_list args;
-
- if (xendev) {
- if (msg_level > xendev->debug) {
- return;
- }
- qemu_log("xen be: %s: ", xendev->name);
- if (msg_level == 0) {
- fprintf(stderr, "xen be: %s: ", xendev->name);
- }
- } else {
- if (msg_level > debug) {
- return;
- }
- qemu_log("xen be core: ");
- if (msg_level == 0) {
- fprintf(stderr, "xen be core: ");
- }
- }
- va_start(args, fmt);
- qemu_log_vprintf(fmt, args);
- va_end(args);
- if (msg_level == 0) {
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
- }
- qemu_log_flush();
-}
static int xen_sysdev_init(SysBusDevice *dev)
{
diff --git a/hw/xen/xen_devconfig.c b/hw/xen/xen_devconfig.c
index b7d290df6c..a80e78c0dc 100644
--- a/hw/xen/xen_devconfig.c
+++ b/hw/xen/xen_devconfig.c
@@ -55,7 +55,7 @@ int xen_config_dev_blk(DriveInfo *disk)
const char *filename = qemu_opt_get(disk->opts, "file");
snprintf(device_name, sizeof(device_name), "xvd%c", 'a' + disk->unit);
- xen_be_printf(NULL, 1, "config disk %d [%s]: %s\n",
+ xen_pv_printf(NULL, 1, "config disk %d [%s]: %s\n",
disk->unit, device_name, filename);
xen_config_dev_dirs("vbd", "qdisk", vdev, fe, be, sizeof(fe));
@@ -83,7 +83,7 @@ int xen_config_dev_nic(NICInfo *nic)
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
nic->macaddr.a[0], nic->macaddr.a[1], nic->macaddr.a[2],
nic->macaddr.a[3], nic->macaddr.a[4], nic->macaddr.a[5]);
- xen_be_printf(NULL, 1, "config nic %d: mac=\"%s\"\n", vlan_id, mac);
+ xen_pv_printf(NULL, 1, "config nic %d: mac=\"%s\"\n", vlan_id, mac);
xen_config_dev_dirs("vif", "qnic", vlan_id, fe, be, sizeof(fe));
/* frontend */
diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c
new file mode 100644
index 0000000000..405e15484c
--- /dev/null
+++ b/hw/xen/xen_pvdev.c
@@ -0,0 +1,316 @@
+/*
+ * Xen para-virtualization device
+ *
+ * (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen_pvdev.h"
+
+/* private */
+static int debug;
+
+struct xs_dirs {
+ char *xs_dir;
+ QTAILQ_ENTRY(xs_dirs) list;
+};
+
+static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
+ QTAILQ_HEAD_INITIALIZER(xs_cleanup);
+
+static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs =
+ QTAILQ_HEAD_INITIALIZER(xendevs);
+
+/* ------------------------------------------------------------- */
+
+static void xenstore_cleanup_dir(char *dir)
+{
+ struct xs_dirs *d;
+
+ d = g_malloc(sizeof(*d));
+ d->xs_dir = dir;
+ QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
+}
+
+void xen_config_cleanup(void)
+{
+ struct xs_dirs *d;
+
+ QTAILQ_FOREACH(d, &xs_cleanup, list) {
+ xs_rm(xenstore, 0, d->xs_dir);
+ }
+}
+
+int xenstore_mkdir(char *path, int p)
+{
+ struct xs_permissions perms[2] = {
+ {
+ .id = 0, /* set owner: dom0 */
+ }, {
+ .id = xen_domid,
+ .perms = p,
+ }
+ };
+
+ if (!xs_mkdir(xenstore, 0, path)) {
+ xen_pv_printf(NULL, 0, "xs_mkdir %s: failed\n", path);
+ return -1;
+ }
+ xenstore_cleanup_dir(g_strdup(path));
+
+ if (!xs_set_permissions(xenstore, 0, path, perms, 2)) {
+ xen_pv_printf(NULL, 0, "xs_set_permissions %s: failed\n", path);
+ return -1;
+ }
+ return 0;
+}
+
+int xenstore_write_str(const char *base, const char *node, const char *val)
+{
+ char abspath[XEN_BUFSIZE];
+
+ snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
+ if (!xs_write(xenstore, 0, abspath, val, strlen(val))) {
+ return -1;
+ }
+ return 0;
+}
+
+char *xenstore_read_str(const char *base, const char *node)
+{
+ char abspath[XEN_BUFSIZE];
+ unsigned int len;
+ char *str, *ret = NULL;
+
+ snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
+ str = xs_read(xenstore, 0, abspath, &len);
+ if (str != NULL) {
+ /* move to qemu-allocated memory to make sure
+ * callers can savely g_free() stuff. */
+ ret = g_strdup(str);
+ free(str);
+ }
+ return ret;
+}
+
+int xenstore_write_int(const char *base, const char *node, int ival)
+{
+ char val[12];
+
+ snprintf(val, sizeof(val), "%d", ival);
+ return xenstore_write_str(base, node, val);
+}
+
+int xenstore_write_int64(const char *base, const char *node, int64_t ival)
+{
+ char val[21];
+
+ snprintf(val, sizeof(val), "%"PRId64, ival);
+ return xenstore_write_str(base, node, val);
+}
+
+int xenstore_read_int(const char *base, const char *node, int *ival)
+{
+ char *val;
+ int rc = -1;
+
+ val = xenstore_read_str(base, node);
+ if (val && 1 == sscanf(val, "%d", ival)) {
+ rc = 0;
+ }
+ g_free(val);
+ return rc;
+}
+
+int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval)
+{
+ char *val;
+ int rc = -1;
+
+ val = xenstore_read_str(base, node);
+ if (val && 1 == sscanf(val, "%"SCNu64, uval)) {
+ rc = 0;
+ }
+ g_free(val);
+ return rc;
+}
+
+void xenstore_update(void *unused)
+{
+ char **vec = NULL;
+ intptr_t type, ops, ptr;
+ unsigned int dom, count;
+
+ vec = xs_read_watch(xenstore, &count);
+ if (vec == NULL) {
+ goto cleanup;
+ }
+
+ if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR,
+ &type, &dom, &ops) == 3) {
+ xenstore_update_be(vec[XS_WATCH_PATH], (void *)type, dom, (void*)ops);
+ }
+ if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) {
+ xenstore_update_fe(vec[XS_WATCH_PATH], (void *)ptr);
+ }
+
+cleanup:
+ free(vec);
+}
+
+const char *xenbus_strstate(enum xenbus_state state)
+{
+ static const char *const name[] = {
+ [XenbusStateUnknown] = "Unknown",
+ [XenbusStateInitialising] = "Initialising",
+ [XenbusStateInitWait] = "InitWait",
+ [XenbusStateInitialised] = "Initialised",
+ [XenbusStateConnected] = "Connected",
+ [XenbusStateClosing] = "Closing",
+ [XenbusStateClosed] = "Closed",
+ };
+ return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
+}
+
+/*
+ * msg_level:
+ * 0 == errors (stderr + logfile).
+ * 1 == informative debug messages (logfile only).
+ * 2 == noisy debug messages (logfile only).
+ * 3 == will flood your log (logfile only).
+ */
+void xen_pv_printf(struct XenDevice *xendev, int msg_level,
+ const char *fmt, ...)
+{
+ va_list args;
+
+ if (xendev) {
+ if (msg_level > xendev->debug) {
+ return;
+ }
+ qemu_log("xen be: %s: ", xendev->name);
+ if (msg_level == 0) {
+ fprintf(stderr, "xen be: %s: ", xendev->name);
+ }
+ } else {
+ if (msg_level > debug) {
+ return;
+ }
+ qemu_log("xen be core: ");
+ if (msg_level == 0) {
+ fprintf(stderr, "xen be core: ");
+ }
+ }
+ va_start(args, fmt);
+ qemu_log_vprintf(fmt, args);
+ va_end(args);
+ if (msg_level == 0) {
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ }
+ qemu_log_flush();
+}
+
+void xen_pv_evtchn_event(void *opaque)
+{
+ struct XenDevice *xendev = opaque;
+ evtchn_port_t port;
+
+ port = xenevtchn_pending(xendev->evtchndev);
+ if (port != xendev->local_port) {
+ xen_pv_printf(xendev, 0,
+ "xenevtchn_pending returned %d (expected %d)\n",
+ port, xendev->local_port);
+ return;
+ }
+ xenevtchn_unmask(xendev->evtchndev, port);
+
+ if (xendev->ops->event) {
+ xendev->ops->event(xendev);
+ }
+}
+
+void xen_pv_unbind_evtchn(struct XenDevice *xendev)
+{
+ if (xendev->local_port == -1) {
+ return;
+ }
+ qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
+ xenevtchn_unbind(xendev->evtchndev, xendev->local_port);
+ xen_pv_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
+ xendev->local_port = -1;
+}
+
+int xen_pv_send_notify(struct XenDevice *xendev)
+{
+ return xenevtchn_notify(xendev->evtchndev, xendev->local_port);
+}
+
+/* ------------------------------------------------------------- */
+
+struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev)
+{
+ struct XenDevice *xendev;
+
+ QTAILQ_FOREACH(xendev, &xendevs, next) {
+ if (xendev->dom != dom) {
+ continue;
+ }
+ if (xendev->dev != dev) {
+ continue;
+ }
+ if (strcmp(xendev->type, type) != 0) {
+ continue;
+ }
+ return xendev;
+ }
+ return NULL;
+}
+
+/*
+ * release xen backend device.
+ */
+void xen_pv_del_xendev(struct XenDevice *xendev)
+{
+ if (xendev->ops->free) {
+ xendev->ops->free(xendev);
+ }
+
+ if (xendev->fe) {
+ char token[XEN_BUFSIZE];
+ snprintf(token, sizeof(token), "fe:%p", xendev);
+ xs_unwatch(xenstore, xendev->fe, token);
+ g_free(xendev->fe);
+ }
+
+ if (xendev->evtchndev != NULL) {
+ xenevtchn_close(xendev->evtchndev);
+ }
+ if (xendev->gnttabdev != NULL) {
+ xengnttab_close(xendev->gnttabdev);
+ }
+
+ QTAILQ_REMOVE(&xendevs, xendev, next);
+ g_free(xendev);
+}
+
+void xen_pv_insert_xendev(struct XenDevice *xendev)
+{
+ QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
+}