Compare commits
89 Commits
v2.6.0-rc1
...
pull-input
Author | SHA1 | Date | |
---|---|---|---|
|
b065e275a8 | ||
|
ce47d3d427 | ||
|
0263b3a72f | ||
|
2d73837466 | ||
|
1a782629f6 | ||
|
848c4d4480 | ||
|
27a7bbcdf9 | ||
|
441330f714 | ||
|
a263bac192 | ||
|
d44122ecd0 | ||
|
5158ac5830 | ||
|
3ef3dcef56 | ||
|
9bf8027dde | ||
|
3f647b510f | ||
|
c1c71e49bc | ||
|
1759386b7c | ||
|
0145b4e130 | ||
|
c4189d85bc | ||
|
4e876bcf2b | ||
|
40a99aace3 | ||
|
1fd06db03d | ||
|
c229708848 | ||
|
143605a200 | ||
|
af74e865c4 | ||
|
42bb626f7e | ||
|
9ca3003df3 | ||
|
39bf92dd70 | ||
|
a77fd4bb29 | ||
|
4e71220387 | ||
|
4553e10360 | ||
|
dc1ffa6661 | ||
|
3a15cc0e1e | ||
|
5144fe3605 | ||
|
fa49e4656a | ||
|
ca58b45fbe | ||
|
9628af036f | ||
|
8227e2d167 | ||
|
3be4f4d724 | ||
|
24790aefe0 | ||
|
5542417dae | ||
|
28ee01269e | ||
|
f2eb665a11 | ||
|
a110655a06 | ||
|
44d066a2f7 | ||
|
57a6c059a6 | ||
|
7e6bd36d61 | ||
|
696b55017d | ||
|
1a5512bb7e | ||
|
dacca04c8d | ||
|
156f6a10c2 | ||
|
6ff5816478 | ||
|
332a254b66 | ||
|
7548fe3116 | ||
|
8c6597123a | ||
|
c0301fcc81 | ||
|
b3f3fdeb95 | ||
|
ecba19935a | ||
|
089adafdc6 | ||
|
ead5268f21 | ||
|
3ccdbecf80 | ||
|
2e4278b534 | ||
|
a378b49a43 | ||
|
a8f2e5c8ff | ||
|
8a2fad57eb | ||
|
344dc16fae | ||
|
43c696a298 | ||
|
eb41cf78fc | ||
|
2b2cbcadc1 | ||
|
a3973f551d | ||
|
fecb48f744 | ||
|
3d100d0fa9 | ||
|
bab47d9a75 | ||
|
0f8445820f | ||
|
45aa4e8e39 | ||
|
8d0ac88e23 | ||
|
27559c214d | ||
|
3005c2c2fa | ||
|
e380023898 | ||
|
6625d83a6e | ||
|
27d92ebc5e | ||
|
0f9d6bd210 | ||
|
bfb1ac1402 | ||
|
b5ab677189 | ||
|
e0a039e50d | ||
|
91731d5f6d | ||
|
044d65525f | ||
|
74044c8ffc | ||
|
a1555559ab | ||
|
34fe9af09b |
@@ -985,6 +985,7 @@ F: tests/intel-hda-test.c
|
||||
|
||||
Block layer core
|
||||
M: Kevin Wolf <kwolf@redhat.com>
|
||||
M: Max Reitz <mreitz@redhat.com>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block*
|
||||
@@ -998,6 +999,7 @@ T: git git://repo.or.cz/qemu/kevin.git block
|
||||
|
||||
Block I/O path
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
M: Fam Zheng <famz@redhat.com>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: async.c
|
||||
@@ -1568,6 +1570,7 @@ F: block/win32-aio.c
|
||||
|
||||
qcow2
|
||||
M: Kevin Wolf <kwolf@redhat.com>
|
||||
M: Max Reitz <mreitz@redhat.com>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block/qcow2*
|
||||
@@ -1580,6 +1583,7 @@ F: block/qcow.c
|
||||
|
||||
blkdebug
|
||||
M: Kevin Wolf <kwolf@redhat.com>
|
||||
M: Max Reitz <mreitz@redhat.com>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block/blkdebug.c
|
||||
|
@@ -52,11 +52,14 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
||||
error_setg(errp, "-mem-path not supported on this host");
|
||||
#else
|
||||
if (!memory_region_size(&backend->mr)) {
|
||||
gchar *path;
|
||||
backend->force_prealloc = mem_prealloc;
|
||||
path = object_get_canonical_path(OBJECT(backend));
|
||||
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
|
||||
object_get_canonical_path(OBJECT(backend)),
|
||||
path,
|
||||
backend->size, fb->share,
|
||||
fb->mem_path, errp);
|
||||
g_free(path);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
45
block/io.c
45
block/io.c
@@ -253,6 +253,47 @@ static void bdrv_drain_recurse(BlockDriverState *bs)
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Coroutine *co;
|
||||
BlockDriverState *bs;
|
||||
QEMUBH *bh;
|
||||
bool done;
|
||||
} BdrvCoDrainData;
|
||||
|
||||
static void bdrv_co_drain_bh_cb(void *opaque)
|
||||
{
|
||||
BdrvCoDrainData *data = opaque;
|
||||
Coroutine *co = data->co;
|
||||
|
||||
qemu_bh_delete(data->bh);
|
||||
bdrv_drain(data->bs);
|
||||
data->done = true;
|
||||
qemu_coroutine_enter(co, NULL);
|
||||
}
|
||||
|
||||
void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
|
||||
{
|
||||
BdrvCoDrainData data;
|
||||
|
||||
/* Calling bdrv_drain() from a BH ensures the current coroutine yields and
|
||||
* other coroutines run if they were queued from
|
||||
* qemu_co_queue_run_restart(). */
|
||||
|
||||
assert(qemu_in_coroutine());
|
||||
data = (BdrvCoDrainData) {
|
||||
.co = qemu_coroutine_self(),
|
||||
.bs = bs,
|
||||
.done = false,
|
||||
.bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_drain_bh_cb, &data),
|
||||
};
|
||||
qemu_bh_schedule(data.bh);
|
||||
|
||||
qemu_coroutine_yield();
|
||||
/* If we are resumed from some other event (such as an aio completion or a
|
||||
* timer callback), it is a bug in the caller that should be fixed. */
|
||||
assert(data.done);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for pending requests to complete on a single BlockDriverState subtree,
|
||||
* and suspend block driver's internal I/O until next request arrives.
|
||||
@@ -269,6 +310,10 @@ void bdrv_drain(BlockDriverState *bs)
|
||||
bool busy = true;
|
||||
|
||||
bdrv_drain_recurse(bs);
|
||||
if (qemu_in_coroutine()) {
|
||||
bdrv_co_drain(bs);
|
||||
return;
|
||||
}
|
||||
while (busy) {
|
||||
/* Keep iterating */
|
||||
bdrv_flush_io_queue(bs);
|
||||
|
@@ -650,7 +650,7 @@ static void coroutine_fn mirror_run(void *opaque)
|
||||
* mirror_populate runs.
|
||||
*/
|
||||
trace_mirror_before_drain(s, cnt);
|
||||
bdrv_drain(bs);
|
||||
bdrv_co_drain(bs);
|
||||
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
|
||||
}
|
||||
|
||||
|
@@ -1986,6 +1986,10 @@ static int qcow2_change_backing_file(BlockDriverState *bs,
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
|
||||
if (backing_file && strlen(backing_file) > 1023) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_file ?: "");
|
||||
pstrcpy(bs->backing_format, sizeof(bs->backing_format), backing_fmt ?: "");
|
||||
|
||||
|
@@ -775,7 +775,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
|
||||
num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);
|
||||
|
||||
ret = blk_pwrite(blk, offset, buf, HEADER_SIZE);
|
||||
if (ret) {
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@@ -185,9 +185,9 @@ an MMIO region mapped at 0x0, size 0x6000, priority 1. B currently has two
|
||||
of its own subregions: D of size 0x1000 at offset 0 and E of size 0x1000 at
|
||||
offset 0x2000. As a diagram:
|
||||
|
||||
0 1000 2000 3000 4000 5000 6000 7000 8000
|
||||
|------|------|------|------|------|------|------|-------|
|
||||
A: [ ]
|
||||
0 1000 2000 3000 4000 5000 6000 7000 8000
|
||||
|------|------|------|------|------|------|------|------|
|
||||
A: [ ]
|
||||
C: [CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC]
|
||||
B: [ ]
|
||||
D: [DDDDD]
|
||||
@@ -247,7 +247,7 @@ system_memory: container@0-2^48-1
|
||||
|
|
||||
+---- himem: alias@0x100000000-0x11fffffff ---> #ram (0xe0000000-0xffffffff)
|
||||
|
|
||||
+---- vga-window: alias@0xa0000-0xbfffff ---> #pci (0xa0000-0xbffff)
|
||||
+---- vga-window: alias@0xa0000-0xbffff ---> #pci (0xa0000-0xbffff)
|
||||
| (prio 1)
|
||||
|
|
||||
+---- pci-hole: alias@0xe0000000-0xffffffff ---> #pci (0xe0000000-0xffffffff)
|
||||
|
@@ -29,7 +29,6 @@
|
||||
struct VirtIOBlockDataPlane {
|
||||
bool starting;
|
||||
bool stopping;
|
||||
bool disabled;
|
||||
|
||||
VirtIOBlkConf *conf;
|
||||
|
||||
@@ -185,6 +184,17 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
|
||||
g_free(s);
|
||||
}
|
||||
|
||||
static void virtio_blk_data_plane_handle_output(VirtIODevice *vdev,
|
||||
VirtQueue *vq)
|
||||
{
|
||||
VirtIOBlock *s = (VirtIOBlock *)vdev;
|
||||
|
||||
assert(s->dataplane);
|
||||
assert(s->dataplane_started);
|
||||
|
||||
virtio_blk_handle_vq(s, vq);
|
||||
}
|
||||
|
||||
/* Context: QEMU global mutex held */
|
||||
void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
||||
{
|
||||
@@ -227,14 +237,15 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
||||
|
||||
/* Get this show started by hooking up our callbacks */
|
||||
aio_context_acquire(s->ctx);
|
||||
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, true, true);
|
||||
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx,
|
||||
virtio_blk_data_plane_handle_output);
|
||||
aio_context_release(s->ctx);
|
||||
return;
|
||||
|
||||
fail_host_notifier:
|
||||
k->set_guest_notifiers(qbus->parent, 1, false);
|
||||
fail_guest_notifiers:
|
||||
s->disabled = true;
|
||||
vblk->dataplane_disabled = true;
|
||||
s->starting = false;
|
||||
vblk->dataplane_started = true;
|
||||
}
|
||||
@@ -251,8 +262,8 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
||||
}
|
||||
|
||||
/* Better luck next time. */
|
||||
if (s->disabled) {
|
||||
s->disabled = false;
|
||||
if (vblk->dataplane_disabled) {
|
||||
vblk->dataplane_disabled = false;
|
||||
vblk->dataplane_started = false;
|
||||
return;
|
||||
}
|
||||
@@ -262,7 +273,7 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
||||
aio_context_acquire(s->ctx);
|
||||
|
||||
/* Stop notifications for new requests from guest */
|
||||
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, false, false);
|
||||
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, NULL);
|
||||
|
||||
/* Drain and switch bs back to the QEMU main loop */
|
||||
blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context());
|
||||
|
@@ -54,7 +54,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
|
||||
|
||||
stb_p(&req->in->status, status);
|
||||
virtqueue_push(s->vq, &req->elem, req->in_len);
|
||||
if (s->dataplane) {
|
||||
if (s->dataplane_started && !s->dataplane_disabled) {
|
||||
virtio_blk_data_plane_notify(s->dataplane);
|
||||
} else {
|
||||
virtio_notify(vdev, s->vq);
|
||||
@@ -578,20 +578,11 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||
void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
|
||||
{
|
||||
VirtIOBlock *s = VIRTIO_BLK(vdev);
|
||||
VirtIOBlockReq *req;
|
||||
MultiReqBuffer mrb = {};
|
||||
|
||||
/* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
|
||||
* dataplane here instead of waiting for .set_status().
|
||||
*/
|
||||
if (s->dataplane && !s->dataplane_started) {
|
||||
virtio_blk_data_plane_start(s->dataplane);
|
||||
return;
|
||||
}
|
||||
|
||||
blk_io_plug(s->blk);
|
||||
|
||||
while ((req = virtio_blk_get_request(s))) {
|
||||
@@ -605,6 +596,22 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||
blk_io_unplug(s->blk);
|
||||
}
|
||||
|
||||
static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||
{
|
||||
VirtIOBlock *s = (VirtIOBlock *)vdev;
|
||||
|
||||
if (s->dataplane) {
|
||||
/* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
|
||||
* dataplane here instead of waiting for .set_status().
|
||||
*/
|
||||
virtio_blk_data_plane_start(s->dataplane);
|
||||
if (!s->dataplane_disabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
virtio_blk_handle_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_blk_dma_restart_bh(void *opaque)
|
||||
{
|
||||
VirtIOBlock *s = opaque;
|
||||
|
@@ -1053,6 +1053,20 @@ void rom_set_fw(FWCfgState *f)
|
||||
fw_cfg = f;
|
||||
}
|
||||
|
||||
void rom_set_order_override(int order)
|
||||
{
|
||||
if (!fw_cfg)
|
||||
return;
|
||||
fw_cfg_set_order_override(fw_cfg, order);
|
||||
}
|
||||
|
||||
void rom_reset_order_override(void)
|
||||
{
|
||||
if (!fw_cfg)
|
||||
return;
|
||||
fw_cfg_reset_order_override(fw_cfg);
|
||||
}
|
||||
|
||||
static Rom *find_rom(hwaddr addr)
|
||||
{
|
||||
Rom *rom;
|
||||
|
@@ -572,10 +572,7 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
|
||||
scanout->width != ss.r.width ||
|
||||
scanout->height != ss.r.height) {
|
||||
/* realloc the surface ptr */
|
||||
scanout->ds = qemu_create_displaysurface_from
|
||||
(ss.r.width, ss.r.height, format,
|
||||
pixman_image_get_stride(res->image),
|
||||
(uint8_t *)pixman_image_get_data(res->image) + offset);
|
||||
scanout->ds = qemu_create_displaysurface_pixman(res->image);
|
||||
if (!scanout->ds) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
|
||||
return;
|
||||
@@ -920,6 +917,11 @@ const GraphicHwOps virtio_gpu_ops = {
|
||||
.gl_block = virtio_gpu_gl_block,
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_virtio_gpu_unmigratable = {
|
||||
.name = "virtio-gpu",
|
||||
.unmigratable = 1,
|
||||
};
|
||||
|
||||
static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
|
||||
{
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
|
||||
@@ -971,6 +973,8 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
|
||||
dpy_gfx_replace_surface(g->scanout[i].con, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
vmstate_register(qdev, -1, &vmstate_virtio_gpu_unmigratable, g);
|
||||
}
|
||||
|
||||
static void virtio_gpu_instance_init(Object *obj)
|
||||
|
@@ -1406,6 +1406,7 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
|
||||
{
|
||||
DeviceState *dev = NULL;
|
||||
|
||||
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_VGA);
|
||||
if (pci_bus) {
|
||||
PCIDevice *pcidev = pci_vga_init(pci_bus);
|
||||
dev = pcidev ? &pcidev->qdev : NULL;
|
||||
@@ -1413,6 +1414,7 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
|
||||
ISADevice *isadev = isa_vga_init(isa_bus);
|
||||
dev = isadev ? DEVICE(isadev) : NULL;
|
||||
}
|
||||
rom_reset_order_override();
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -1541,6 +1543,7 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus)
|
||||
{
|
||||
int i;
|
||||
|
||||
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_NIC);
|
||||
for (i = 0; i < nb_nics; i++) {
|
||||
NICInfo *nd = &nd_table[i];
|
||||
|
||||
@@ -1550,6 +1553,7 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus)
|
||||
pci_nic_init_nofail(nd, pci_bus, "e1000", NULL);
|
||||
}
|
||||
}
|
||||
rom_reset_order_override();
|
||||
}
|
||||
|
||||
void pc_pci_device_init(PCIBus *pci_bus)
|
||||
|
@@ -434,6 +434,7 @@ static void pc_i440fx_2_5_machine_options(MachineClass *m)
|
||||
m->alias = NULL;
|
||||
m->is_default = 0;
|
||||
pcmc->save_tsc_khz = false;
|
||||
m->legacy_fw_cfg_order = 1;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
|
||||
}
|
||||
|
||||
|
@@ -298,6 +298,7 @@ static void pc_q35_2_5_machine_options(MachineClass *m)
|
||||
pc_q35_2_6_machine_options(m);
|
||||
m->alias = NULL;
|
||||
pcmc->save_tsc_khz = false;
|
||||
m->legacy_fw_cfg_order = 1;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
|
||||
}
|
||||
|
||||
|
@@ -258,22 +258,10 @@ static const TypeInfo piix3_ide_info = {
|
||||
.class_init = piix3_ide_class_init,
|
||||
};
|
||||
|
||||
static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->realize = pci_piix_ide_realize;
|
||||
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
|
||||
k->class_id = PCI_CLASS_STORAGE_IDE;
|
||||
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
|
||||
}
|
||||
|
||||
static const TypeInfo piix3_ide_xen_info = {
|
||||
.name = "piix3-ide-xen",
|
||||
.parent = TYPE_PCI_IDE,
|
||||
.class_init = piix3_ide_xen_class_init,
|
||||
.class_init = piix3_ide_class_init,
|
||||
};
|
||||
|
||||
static void piix4_ide_class_init(ObjectClass *klass, void *data)
|
||||
|
@@ -628,7 +628,7 @@ static void ps2_kbd_reset(void *opaque)
|
||||
ps2_common_reset(&s->common);
|
||||
s->scan_enabled = 0;
|
||||
s->translate = 0;
|
||||
s->scancode_set = 0;
|
||||
s->scancode_set = 2;
|
||||
}
|
||||
|
||||
static void ps2_mouse_reset(void *opaque)
|
||||
|
@@ -121,6 +121,8 @@ static const unsigned int keymap_qcode[Q_KEY_CODE__MAX] = {
|
||||
|
||||
[Q_KEY_CODE_CTRL_R] = KEY_RIGHTCTRL,
|
||||
[Q_KEY_CODE_SYSRQ] = KEY_SYSRQ,
|
||||
[Q_KEY_CODE_PRINT] = KEY_SYSRQ,
|
||||
[Q_KEY_CODE_PAUSE] = KEY_PAUSE,
|
||||
[Q_KEY_CODE_ALT_R] = KEY_RIGHTALT,
|
||||
|
||||
[Q_KEY_CODE_HOME] = KEY_HOME,
|
||||
@@ -482,12 +484,12 @@ static struct virtio_input_config virtio_tablet_config[] = {
|
||||
.select = VIRTIO_INPUT_CFG_ABS_INFO,
|
||||
.subsel = ABS_X,
|
||||
.size = sizeof(virtio_input_absinfo),
|
||||
.u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE),
|
||||
.u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
|
||||
},{
|
||||
.select = VIRTIO_INPUT_CFG_ABS_INFO,
|
||||
.subsel = ABS_Y,
|
||||
.size = sizeof(virtio_input_absinfo),
|
||||
.u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE),
|
||||
.u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
|
||||
},
|
||||
{ /* end of list */ },
|
||||
};
|
||||
|
@@ -70,13 +70,39 @@ static void virtio_input_bits_config(VirtIOInputHost *vih,
|
||||
virtio_input_add_config(VIRTIO_INPUT(vih), &bits);
|
||||
}
|
||||
|
||||
static void virtio_input_abs_config(VirtIOInputHost *vih, int axis)
|
||||
{
|
||||
virtio_input_config config;
|
||||
struct input_absinfo absinfo;
|
||||
int rc;
|
||||
|
||||
rc = ioctl(vih->fd, EVIOCGABS(axis), &absinfo);
|
||||
if (rc < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.select = VIRTIO_INPUT_CFG_ABS_INFO;
|
||||
config.subsel = axis;
|
||||
config.size = sizeof(virtio_input_absinfo);
|
||||
|
||||
config.u.abs.min = cpu_to_le32(absinfo.minimum);
|
||||
config.u.abs.max = cpu_to_le32(absinfo.maximum);
|
||||
config.u.abs.fuzz = cpu_to_le32(absinfo.fuzz);
|
||||
config.u.abs.flat = cpu_to_le32(absinfo.flat);
|
||||
config.u.abs.res = cpu_to_le32(absinfo.resolution);
|
||||
|
||||
virtio_input_add_config(VIRTIO_INPUT(vih), &config);
|
||||
}
|
||||
|
||||
static void virtio_input_host_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev);
|
||||
VirtIOInput *vinput = VIRTIO_INPUT(dev);
|
||||
virtio_input_config id;
|
||||
virtio_input_config id, *abs;
|
||||
struct input_id ids;
|
||||
int rc, ver;
|
||||
int rc, ver, i, axis;
|
||||
uint8_t byte;
|
||||
|
||||
if (!vih->evdev) {
|
||||
error_setg(errp, "evdev property is required");
|
||||
@@ -125,6 +151,23 @@ static void virtio_input_host_realize(DeviceState *dev, Error **errp)
|
||||
virtio_input_bits_config(vih, EV_ABS, ABS_CNT);
|
||||
virtio_input_bits_config(vih, EV_MSC, MSC_CNT);
|
||||
virtio_input_bits_config(vih, EV_SW, SW_CNT);
|
||||
virtio_input_bits_config(vih, EV_LED, LED_CNT);
|
||||
|
||||
abs = virtio_input_find_config(VIRTIO_INPUT(vih),
|
||||
VIRTIO_INPUT_CFG_EV_BITS, EV_ABS);
|
||||
if (abs) {
|
||||
for (i = 0; i < abs->size; i++) {
|
||||
byte = abs->u.bitmap[i];
|
||||
axis = 8 * i;
|
||||
while (byte) {
|
||||
if (byte & 1) {
|
||||
virtio_input_abs_config(vih, axis);
|
||||
}
|
||||
axis++;
|
||||
byte >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih);
|
||||
return;
|
||||
@@ -145,6 +188,28 @@ static void virtio_input_host_unrealize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_input_host_handle_status(VirtIOInput *vinput,
|
||||
virtio_input_event *event)
|
||||
{
|
||||
VirtIOInputHost *vih = VIRTIO_INPUT_HOST(vinput);
|
||||
struct input_event evdev;
|
||||
int rc;
|
||||
|
||||
if (gettimeofday(&evdev.time, NULL)) {
|
||||
perror("virtio_input_host_handle_status: gettimeofday");
|
||||
return;
|
||||
}
|
||||
|
||||
evdev.type = le16_to_cpu(event->type);
|
||||
evdev.code = le16_to_cpu(event->code);
|
||||
evdev.value = le32_to_cpu(event->value);
|
||||
|
||||
rc = write(vih->fd, &evdev, sizeof(evdev));
|
||||
if (rc == -1) {
|
||||
perror("virtio_input_host_handle_status: write");
|
||||
}
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_virtio_input_host = {
|
||||
.name = "virtio-input-host",
|
||||
.unmigratable = 1,
|
||||
@@ -164,6 +229,7 @@ static void virtio_input_host_class_init(ObjectClass *klass, void *data)
|
||||
dc->props = virtio_input_host_properties;
|
||||
vic->realize = virtio_input_host_realize;
|
||||
vic->unrealize = virtio_input_host_unrealize;
|
||||
vic->handle_status = virtio_input_host_handle_status;
|
||||
}
|
||||
|
||||
static void virtio_input_host_init(Object *obj)
|
||||
|
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "standard-headers/linux/input.h"
|
||||
|
||||
#define VIRTIO_INPUT_VM_VERSION 1
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
|
||||
@@ -97,9 +99,9 @@ static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq)
|
||||
virtio_notify(vdev, vinput->sts);
|
||||
}
|
||||
|
||||
static virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
|
||||
uint8_t select,
|
||||
uint8_t subsel)
|
||||
virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
|
||||
uint8_t select,
|
||||
uint8_t subsel)
|
||||
{
|
||||
VirtIOInputConfig *cfg;
|
||||
|
||||
@@ -214,6 +216,38 @@ static void virtio_input_reset(VirtIODevice *vdev)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_input_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
VirtIOInput *vinput = opaque;
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(vinput);
|
||||
|
||||
virtio_save(vdev, f);
|
||||
}
|
||||
|
||||
static int virtio_input_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
VirtIOInput *vinput = opaque;
|
||||
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vinput);
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(vinput);
|
||||
int ret;
|
||||
|
||||
if (version_id != VIRTIO_INPUT_VM_VERSION) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = virtio_load(vdev, f, version_id);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* post_load() */
|
||||
vinput->active = vdev->status & VIRTIO_CONFIG_S_DRIVER_OK;
|
||||
if (vic->change_active) {
|
||||
vic->change_active(vinput);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void virtio_input_device_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
|
||||
@@ -245,14 +279,20 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp)
|
||||
vinput->cfg_size);
|
||||
vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt);
|
||||
vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts);
|
||||
|
||||
register_savevm(dev, "virtio-input", -1, VIRTIO_INPUT_VM_VERSION,
|
||||
virtio_input_save, virtio_input_load, vinput);
|
||||
}
|
||||
|
||||
static void virtio_input_device_unrealize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
||||
VirtIOInput *vinput = VIRTIO_INPUT(dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
unregister_savevm(dev, "virtio-input", vinput);
|
||||
|
||||
if (vic->unrealize) {
|
||||
vic->unrealize(dev, &local_err);
|
||||
if (local_err) {
|
||||
|
@@ -66,18 +66,13 @@ static uint64_t itc_tag_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
MIPSITUState *tag = (MIPSITUState *)opaque;
|
||||
uint64_t index = addr >> 3;
|
||||
uint64_t ret = 0;
|
||||
|
||||
switch (index) {
|
||||
case 0 ... ITC_ADDRESSMAP_NUM:
|
||||
ret = tag->ITCAddressMap[index];
|
||||
break;
|
||||
default:
|
||||
if (index >= ITC_ADDRESSMAP_NUM) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Read 0x%" PRIx64 "\n", addr);
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return tag->ITCAddressMap[index];
|
||||
}
|
||||
|
||||
static void itc_reconfigure(MIPSITUState *tag)
|
||||
|
@@ -239,6 +239,7 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp)
|
||||
uint8_t *pci_conf;
|
||||
char *name;
|
||||
int r, i;
|
||||
bool fastmmio = kvm_ioeventfd_any_length_enabled();
|
||||
|
||||
pci_conf = pci_dev->config;
|
||||
|
||||
@@ -261,8 +262,12 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp)
|
||||
memcpy(test->hdr->name, name, strlen(name) + 1);
|
||||
g_free(name);
|
||||
test->hdr->offset = cpu_to_le32(IOTEST_SIZE(i) + i * IOTEST_ACCESS_WIDTH);
|
||||
test->size = IOTEST_ACCESS_WIDTH;
|
||||
test->match_data = strcmp(IOTEST_TEST(i), "wildcard-eventfd");
|
||||
if (fastmmio && IOTEST_IS_MEM(i) && !test->match_data) {
|
||||
test->size = 0;
|
||||
} else {
|
||||
test->size = IOTEST_ACCESS_WIDTH;
|
||||
}
|
||||
test->hdr->test = i;
|
||||
test->hdr->data = test->match_data ? IOTEST_DATAMATCH : IOTEST_NOMATCH;
|
||||
test->hdr->width = IOTEST_ACCESS_WIDTH;
|
||||
|
@@ -85,7 +85,7 @@ static void mii_reset(Mii *s)
|
||||
{
|
||||
memset(s->regs, 0, sizeof(s->regs));
|
||||
s->regs[MII_BMCR] = 0x1000;
|
||||
s->regs[MII_BMSR] = 0x7848; /* no ext regs */
|
||||
s->regs[MII_BMSR] = 0x7868; /* no ext regs */
|
||||
s->regs[MII_PHYIDR1] = 0x2000;
|
||||
s->regs[MII_PHYIDR2] = 0x5c90;
|
||||
s->regs[MII_ANAR] = 0x01e1;
|
||||
|
@@ -2046,7 +2046,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
|
||||
}
|
||||
|
||||
/* transfer ownership to target */
|
||||
txdw0 &= ~CP_RX_OWN;
|
||||
txdw0 &= ~CP_TX_OWN;
|
||||
|
||||
/* reset error indicator bits */
|
||||
txdw0 &= ~CP_TX_STATUS_UNF;
|
||||
|
@@ -236,8 +236,18 @@ static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, si
|
||||
n = s->next_packet + s->np;
|
||||
if (n >= 31)
|
||||
n -= 31;
|
||||
s->np++;
|
||||
|
||||
if (size >= sizeof(s->rx[n].data) - 6) {
|
||||
/* If the packet won't fit into the
|
||||
* emulated 2K RAM, this is reported
|
||||
* as a FIFO overrun error.
|
||||
*/
|
||||
s->ris |= SE_INT_FOV;
|
||||
stellaris_enet_update(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->np++;
|
||||
s->rx[n].len = size + 6;
|
||||
p = s->rx[n].data;
|
||||
*(p++) = (size + 6);
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#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"
|
||||
@@ -69,11 +70,14 @@ struct FWCfgState {
|
||||
/*< public >*/
|
||||
|
||||
FWCfgEntry entries[2][FW_CFG_MAX_ENTRY];
|
||||
int entry_order[FW_CFG_MAX_ENTRY];
|
||||
FWCfgFiles *files;
|
||||
uint16_t cur_entry;
|
||||
uint32_t cur_offset;
|
||||
Notifier machine_ready;
|
||||
|
||||
int fw_cfg_order_override;
|
||||
|
||||
bool dma_enabled;
|
||||
dma_addr_t dma_addr;
|
||||
AddressSpace *dma_as;
|
||||
@@ -665,12 +669,87 @@ void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
|
||||
fw_cfg_add_bytes(s, key, copy, sizeof(value));
|
||||
}
|
||||
|
||||
void fw_cfg_set_order_override(FWCfgState *s, int order)
|
||||
{
|
||||
assert(s->fw_cfg_order_override == 0);
|
||||
s->fw_cfg_order_override = order;
|
||||
}
|
||||
|
||||
void fw_cfg_reset_order_override(FWCfgState *s)
|
||||
{
|
||||
assert(s->fw_cfg_order_override != 0);
|
||||
s->fw_cfg_order_override = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the legacy order list. For legacy systems, files are in
|
||||
* the fw_cfg in the order defined below, by the "order" value. Note
|
||||
* that some entries (VGA ROMs, NIC option ROMS, etc.) go into a
|
||||
* specific area, but there may be more than one and they occur in the
|
||||
* order that the user specifies them on the command line. Those are
|
||||
* handled in a special manner, using the order override above.
|
||||
*
|
||||
* For non-legacy, the files are sorted by filename to avoid this kind
|
||||
* of complexity in the future.
|
||||
*
|
||||
* This is only for x86, other arches don't implement versioning so
|
||||
* they won't set legacy mode.
|
||||
*/
|
||||
static struct {
|
||||
const char *name;
|
||||
int order;
|
||||
} fw_cfg_order[] = {
|
||||
{ "etc/boot-menu-wait", 10 },
|
||||
{ "bootsplash.jpg", 11 },
|
||||
{ "bootsplash.bmp", 12 },
|
||||
{ "etc/boot-fail-wait", 15 },
|
||||
{ "etc/smbios/smbios-tables", 20 },
|
||||
{ "etc/smbios/smbios-anchor", 30 },
|
||||
{ "etc/e820", 40 },
|
||||
{ "etc/reserved-memory-end", 50 },
|
||||
{ "genroms/kvmvapic.bin", 55 },
|
||||
{ "genroms/linuxboot.bin", 60 },
|
||||
{ }, /* VGA ROMs from pc_vga_init come here, 70. */
|
||||
{ }, /* NIC option ROMs from pc_nic_init come here, 80. */
|
||||
{ "etc/system-states", 90 },
|
||||
{ }, /* User ROMs come here, 100. */
|
||||
{ }, /* Device FW comes here, 110. */
|
||||
{ "etc/extra-pci-roots", 120 },
|
||||
{ "etc/acpi/tables", 130 },
|
||||
{ "etc/table-loader", 140 },
|
||||
{ "etc/tpm/log", 150 },
|
||||
{ "etc/acpi/rsdp", 160 },
|
||||
{ "bootorder", 170 },
|
||||
|
||||
#define FW_CFG_ORDER_OVERRIDE_LAST 200
|
||||
};
|
||||
|
||||
static int get_fw_cfg_order(FWCfgState *s, const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (s->fw_cfg_order_override > 0)
|
||||
return s->fw_cfg_order_override;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fw_cfg_order); i++) {
|
||||
if (fw_cfg_order[i].name == NULL)
|
||||
continue;
|
||||
if (strcmp(name, fw_cfg_order[i].name) == 0)
|
||||
return fw_cfg_order[i].order;
|
||||
}
|
||||
/* Stick unknown stuff at the end. */
|
||||
error_report("warning: Unknown firmware file in legacy mode: %s\n", name);
|
||||
return FW_CFG_ORDER_OVERRIDE_LAST;
|
||||
}
|
||||
|
||||
void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
||||
FWCfgReadCallback callback, void *callback_opaque,
|
||||
void *data, size_t len)
|
||||
{
|
||||
int i, index;
|
||||
int i, index, count;
|
||||
size_t dsize;
|
||||
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
|
||||
int order = 0;
|
||||
|
||||
if (!s->files) {
|
||||
dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
|
||||
@@ -678,13 +757,48 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
||||
fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, s->files, dsize);
|
||||
}
|
||||
|
||||
index = be32_to_cpu(s->files->count);
|
||||
assert(index < FW_CFG_FILE_SLOTS);
|
||||
count = be32_to_cpu(s->files->count);
|
||||
assert(count < FW_CFG_FILE_SLOTS);
|
||||
|
||||
pstrcpy(s->files->f[index].name, sizeof(s->files->f[index].name),
|
||||
filename);
|
||||
for (i = 0; i < index; i++) {
|
||||
if (strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
|
||||
/* Find the insertion point. */
|
||||
if (mc->legacy_fw_cfg_order) {
|
||||
/*
|
||||
* Sort by order. For files with the same order, we keep them
|
||||
* in the sequence in which they were added.
|
||||
*/
|
||||
order = get_fw_cfg_order(s, filename);
|
||||
for (index = count;
|
||||
index > 0 && order < s->entry_order[index - 1];
|
||||
index--);
|
||||
} else {
|
||||
/* Sort by file name. */
|
||||
for (index = count;
|
||||
index > 0 && strcmp(filename, s->files->f[index - 1].name) < 0;
|
||||
index--);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move all the entries from the index point and after down one
|
||||
* to create a slot for the new entry. Because calculations are
|
||||
* being done with the index, make it so that "i" is the current
|
||||
* index and "i - 1" is the one being copied from, thus the
|
||||
* unusual start and end in the for statement.
|
||||
*/
|
||||
for (i = count + 1; i > index; i--) {
|
||||
s->files->f[i] = s->files->f[i - 1];
|
||||
s->files->f[i].select = cpu_to_be16(FW_CFG_FILE_FIRST + i);
|
||||
s->entries[0][FW_CFG_FILE_FIRST + i] =
|
||||
s->entries[0][FW_CFG_FILE_FIRST + i - 1];
|
||||
s->entry_order[i] = s->entry_order[i - 1];
|
||||
}
|
||||
|
||||
memset(&s->files->f[index], 0, sizeof(FWCfgFile));
|
||||
memset(&s->entries[0][FW_CFG_FILE_FIRST + index], 0, sizeof(FWCfgEntry));
|
||||
|
||||
pstrcpy(s->files->f[index].name, sizeof(s->files->f[index].name), filename);
|
||||
for (i = 0; i <= count; i++) {
|
||||
if (i != index &&
|
||||
strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
|
||||
error_report("duplicate fw_cfg file name: %s",
|
||||
s->files->f[index].name);
|
||||
exit(1);
|
||||
@@ -696,9 +810,10 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
||||
|
||||
s->files->f[index].size = cpu_to_be32(len);
|
||||
s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
|
||||
s->entry_order[index] = order;
|
||||
trace_fw_cfg_add_file(s, index, s->files->f[index].name, len);
|
||||
|
||||
s->files->count = cpu_to_be32(index+1);
|
||||
s->files->count = cpu_to_be32(count+1);
|
||||
}
|
||||
|
||||
void fw_cfg_add_file(FWCfgState *s, const char *filename,
|
||||
|
@@ -78,6 +78,14 @@ err_bridge:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const VMStateDescription i82801b11_bridge_dev_vmstate = {
|
||||
.name = "i82801b11_bridge",
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
@@ -89,6 +97,7 @@ static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
|
||||
k->revision = ICH9_D2P_A2_REVISION;
|
||||
k->init = i82801b11_bridge_initfn;
|
||||
k->config_write = pci_bridge_write_config;
|
||||
dc->vmsd = &i82801b11_bridge_dev_vmstate;
|
||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||
}
|
||||
|
||||
|
@@ -249,7 +249,7 @@ static int pxb_dev_init_common(PCIDevice *dev, bool pcie)
|
||||
PCI_HOST_BRIDGE(ds)->bus = bus;
|
||||
|
||||
if (pxb_register_bus(dev, bus)) {
|
||||
return -EINVAL;
|
||||
goto err_register_bus;
|
||||
}
|
||||
|
||||
qdev_init_nofail(ds);
|
||||
@@ -263,6 +263,12 @@ static int pxb_dev_init_common(PCIDevice *dev, bool pcie)
|
||||
|
||||
pxb_dev_list = g_list_insert_sorted(pxb_dev_list, pxb, pxb_compare);
|
||||
return 0;
|
||||
|
||||
err_register_bus:
|
||||
object_unref(OBJECT(bds));
|
||||
object_unparent(OBJECT(bus));
|
||||
object_unref(OBJECT(ds));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int pxb_dev_initfn(PCIDevice *dev)
|
||||
|
@@ -2208,6 +2208,10 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
|
||||
if (*errp) {
|
||||
return;
|
||||
}
|
||||
if (node < 0 || node >= MAX_NODES) {
|
||||
error_setg(errp, "Invaild node %d", node);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Currently PowerPC kernel doesn't allow hot-adding memory to
|
||||
|
@@ -684,6 +684,9 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
|
||||
int i;
|
||||
uint32_t lrdr_capacity[5];
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
|
||||
uint64_t max_hotplug_addr = spapr->hotplug_memory.base +
|
||||
memory_region_size(&spapr->hotplug_memory.mr);
|
||||
|
||||
ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
|
||||
if (ret < 0) {
|
||||
@@ -733,8 +736,8 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
|
||||
|
||||
}
|
||||
|
||||
lrdr_capacity[0] = cpu_to_be32(((uint64_t)machine->maxram_size) >> 32);
|
||||
lrdr_capacity[1] = cpu_to_be32(machine->maxram_size & 0xffffffff);
|
||||
lrdr_capacity[0] = cpu_to_be32(max_hotplug_addr >> 32);
|
||||
lrdr_capacity[1] = cpu_to_be32(max_hotplug_addr & 0xffffffff);
|
||||
lrdr_capacity[2] = 0;
|
||||
lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
|
||||
lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
|
||||
|
@@ -38,7 +38,35 @@ void virtio_scsi_set_iothread(VirtIOSCSI *s, IOThread *iothread)
|
||||
}
|
||||
}
|
||||
|
||||
static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n)
|
||||
static void virtio_scsi_data_plane_handle_cmd(VirtIODevice *vdev,
|
||||
VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||
|
||||
assert(s->ctx && s->dataplane_started);
|
||||
virtio_scsi_handle_cmd_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_data_plane_handle_ctrl(VirtIODevice *vdev,
|
||||
VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||
|
||||
assert(s->ctx && s->dataplane_started);
|
||||
virtio_scsi_handle_ctrl_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_data_plane_handle_event(VirtIODevice *vdev,
|
||||
VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||
|
||||
assert(s->ctx && s->dataplane_started);
|
||||
virtio_scsi_handle_event_vq(s, vq);
|
||||
}
|
||||
|
||||
static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n,
|
||||
void (*fn)(VirtIODevice *vdev, VirtQueue *vq))
|
||||
{
|
||||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||
@@ -53,7 +81,7 @@ static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n)
|
||||
return rc;
|
||||
}
|
||||
|
||||
virtio_queue_aio_set_host_notifier_handler(vq, s->ctx, true, true);
|
||||
virtio_queue_aio_set_host_notifier_handler(vq, s->ctx, fn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -70,10 +98,10 @@ static void virtio_scsi_clear_aio(VirtIOSCSI *s)
|
||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
|
||||
int i;
|
||||
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->ctrl_vq, s->ctx, false, false);
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->event_vq, s->ctx, false, false);
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->ctrl_vq, s->ctx, NULL);
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->event_vq, s->ctx, NULL);
|
||||
for (i = 0; i < vs->conf.num_queues; i++) {
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->cmd_vqs[i], s->ctx, false, false);
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->cmd_vqs[i], s->ctx, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,16 +132,19 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s)
|
||||
}
|
||||
|
||||
aio_context_acquire(s->ctx);
|
||||
rc = virtio_scsi_vring_init(s, vs->ctrl_vq, 0);
|
||||
rc = virtio_scsi_vring_init(s, vs->ctrl_vq, 0,
|
||||
virtio_scsi_data_plane_handle_ctrl);
|
||||
if (rc) {
|
||||
goto fail_vrings;
|
||||
}
|
||||
rc = virtio_scsi_vring_init(s, vs->event_vq, 1);
|
||||
rc = virtio_scsi_vring_init(s, vs->event_vq, 1,
|
||||
virtio_scsi_data_plane_handle_event);
|
||||
if (rc) {
|
||||
goto fail_vrings;
|
||||
}
|
||||
for (i = 0; i < vs->conf.num_queues; i++) {
|
||||
rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2);
|
||||
rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2,
|
||||
virtio_scsi_data_plane_handle_cmd);
|
||||
if (rc) {
|
||||
goto fail_vrings;
|
||||
}
|
||||
|
@@ -68,7 +68,7 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
|
||||
|
||||
qemu_iovec_from_buf(&req->resp_iov, 0, &req->resp, req->resp_size);
|
||||
virtqueue_push(vq, &req->elem, req->qsgl.size + req->resp_iov.size);
|
||||
if (s->dataplane_started) {
|
||||
if (s->dataplane_started && !s->dataplane_fenced) {
|
||||
virtio_scsi_dataplane_notify(vdev, req);
|
||||
} else {
|
||||
virtio_notify(vdev, vq);
|
||||
@@ -374,7 +374,7 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
{
|
||||
VirtIODevice *vdev = (VirtIODevice *)s;
|
||||
uint32_t type;
|
||||
@@ -412,20 +412,28 @@ void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
void virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||
VirtIOSCSIReq *req;
|
||||
|
||||
if (s->ctx && !s->dataplane_started) {
|
||||
virtio_scsi_dataplane_start(s);
|
||||
return;
|
||||
}
|
||||
while ((req = virtio_scsi_pop_req(s, vq))) {
|
||||
virtio_scsi_handle_ctrl_req(s, req);
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||
|
||||
if (s->ctx) {
|
||||
virtio_scsi_dataplane_start(s);
|
||||
if (!s->dataplane_fenced) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
virtio_scsi_handle_ctrl_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_complete_cmd_req(VirtIOSCSIReq *req)
|
||||
{
|
||||
/* Sense data is not in req->resp and is copied separately
|
||||
@@ -508,7 +516,7 @@ static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
|
||||
virtio_scsi_complete_cmd_req(req);
|
||||
}
|
||||
|
||||
bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
static bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
{
|
||||
VirtIOSCSICommon *vs = &s->parent_obj;
|
||||
SCSIDevice *d;
|
||||
@@ -550,7 +558,7 @@ bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
return true;
|
||||
}
|
||||
|
||||
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
static void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
{
|
||||
SCSIRequest *sreq = req->sreq;
|
||||
if (scsi_req_enqueue(sreq)) {
|
||||
@@ -560,17 +568,11 @@ void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
scsi_req_unref(sreq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
||||
void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
|
||||
{
|
||||
/* use non-QOM casts in the data path */
|
||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||
VirtIOSCSIReq *req, *next;
|
||||
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
|
||||
|
||||
if (s->ctx && !s->dataplane_started) {
|
||||
virtio_scsi_dataplane_start(s);
|
||||
return;
|
||||
}
|
||||
while ((req = virtio_scsi_pop_req(s, vq))) {
|
||||
if (virtio_scsi_handle_cmd_req_prepare(s, req)) {
|
||||
QTAILQ_INSERT_TAIL(&reqs, req, next);
|
||||
@@ -582,6 +584,20 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
||||
{
|
||||
/* use non-QOM casts in the data path */
|
||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||
|
||||
if (s->ctx) {
|
||||
virtio_scsi_dataplane_start(s);
|
||||
if (!s->dataplane_fenced) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
virtio_scsi_handle_cmd_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_get_config(VirtIODevice *vdev,
|
||||
uint8_t *config)
|
||||
{
|
||||
@@ -725,17 +741,24 @@ out:
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq)
|
||||
{
|
||||
if (s->events_dropped) {
|
||||
virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||
|
||||
if (s->ctx && !s->dataplane_started) {
|
||||
if (s->ctx) {
|
||||
virtio_scsi_dataplane_start(s);
|
||||
return;
|
||||
}
|
||||
if (s->events_dropped) {
|
||||
virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
|
||||
if (!s->dataplane_fenced) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
virtio_scsi_handle_event_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
|
||||
@@ -773,7 +796,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||
SCSIDevice *sd = SCSI_DEVICE(dev);
|
||||
|
||||
if (s->ctx && !s->dataplane_disabled) {
|
||||
if (s->ctx && !s->dataplane_fenced) {
|
||||
VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier;
|
||||
|
||||
if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
|
||||
|
@@ -201,12 +201,7 @@ static void update_irq(struct HPETTimer *timer, int set)
|
||||
if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) {
|
||||
s->isr &= ~mask;
|
||||
if (!timer_fsb_route(timer)) {
|
||||
/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
|
||||
if (route >= ISA_NUM_IRQS) {
|
||||
qemu_irq_raise(s->irqs[route]);
|
||||
} else {
|
||||
qemu_irq_lower(s->irqs[route]);
|
||||
}
|
||||
qemu_irq_lower(s->irqs[route]);
|
||||
}
|
||||
} else if (timer_fsb_route(timer)) {
|
||||
address_space_stl_le(&address_space_memory, timer->fsb >> 32,
|
||||
@@ -214,12 +209,7 @@ static void update_irq(struct HPETTimer *timer, int set)
|
||||
NULL);
|
||||
} else if (timer->config & HPET_TN_TYPE_LEVEL) {
|
||||
s->isr |= mask;
|
||||
/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
|
||||
if (route >= ISA_NUM_IRQS) {
|
||||
qemu_irq_lower(s->irqs[route]);
|
||||
} else {
|
||||
qemu_irq_raise(s->irqs[route]);
|
||||
}
|
||||
qemu_irq_raise(s->irqs[route]);
|
||||
} else {
|
||||
s->isr &= ~mask;
|
||||
qemu_irq_pulse(s->irqs[route]);
|
||||
|
@@ -426,6 +426,10 @@ static int virtio_balloon_load_device(VirtIODevice *vdev, QEMUFile *f,
|
||||
|
||||
s->num_pages = qemu_get_be32(f);
|
||||
s->actual = qemu_get_be32(f);
|
||||
|
||||
if (balloon_stats_enabled(s)) {
|
||||
balloon_stats_change_timer(s, s->stats_poll_interval);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -96,6 +96,7 @@ struct VirtQueue
|
||||
|
||||
uint16_t vector;
|
||||
void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
|
||||
void (*handle_aio_output)(VirtIODevice *vdev, VirtQueue *vq);
|
||||
VirtIODevice *vdev;
|
||||
EventNotifier guest_notifier;
|
||||
EventNotifier host_notifier;
|
||||
@@ -1088,7 +1089,17 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
|
||||
virtio_queue_update_rings(vdev, n);
|
||||
}
|
||||
|
||||
void virtio_queue_notify_vq(VirtQueue *vq)
|
||||
static void virtio_queue_notify_aio_vq(VirtQueue *vq)
|
||||
{
|
||||
if (vq->vring.desc && vq->handle_aio_output) {
|
||||
VirtIODevice *vdev = vq->vdev;
|
||||
|
||||
trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
|
||||
vq->handle_aio_output(vdev, vq);
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_queue_notify_vq(VirtQueue *vq)
|
||||
{
|
||||
if (vq->vring.desc && vq->handle_output) {
|
||||
VirtIODevice *vdev = vq->vdev;
|
||||
@@ -1143,6 +1154,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
|
||||
vdev->vq[i].vring.num_default = queue_size;
|
||||
vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN;
|
||||
vdev->vq[i].handle_output = handle_output;
|
||||
vdev->vq[i].handle_aio_output = NULL;
|
||||
|
||||
return &vdev->vq[i];
|
||||
}
|
||||
@@ -1780,6 +1792,31 @@ EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
|
||||
return &vq->guest_notifier;
|
||||
}
|
||||
|
||||
static void virtio_queue_host_notifier_aio_read(EventNotifier *n)
|
||||
{
|
||||
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
|
||||
if (event_notifier_test_and_clear(n)) {
|
||||
virtio_queue_notify_aio_vq(vq);
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
||||
void (*handle_output)(VirtIODevice *,
|
||||
VirtQueue *))
|
||||
{
|
||||
if (handle_output) {
|
||||
vq->handle_aio_output = handle_output;
|
||||
aio_set_event_notifier(ctx, &vq->host_notifier, true,
|
||||
virtio_queue_host_notifier_aio_read);
|
||||
} else {
|
||||
aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL);
|
||||
/* Test and clear notifier before after disabling event,
|
||||
* in case poll callback didn't have time to run. */
|
||||
virtio_queue_host_notifier_aio_read(&vq->host_notifier);
|
||||
vq->handle_aio_output = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_queue_host_notifier_read(EventNotifier *n)
|
||||
{
|
||||
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
|
||||
@@ -1788,22 +1825,6 @@ static void virtio_queue_host_notifier_read(EventNotifier *n)
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
||||
bool assign, bool set_handler)
|
||||
{
|
||||
if (assign && set_handler) {
|
||||
aio_set_event_notifier(ctx, &vq->host_notifier, true,
|
||||
virtio_queue_host_notifier_read);
|
||||
} else {
|
||||
aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL);
|
||||
}
|
||||
if (!assign) {
|
||||
/* Test and clear notifier before after disabling event,
|
||||
* in case poll callback didn't have time to run. */
|
||||
virtio_queue_host_notifier_read(&vq->host_notifier);
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
|
||||
bool set_handler)
|
||||
{
|
||||
|
@@ -372,6 +372,7 @@ int bdrv_flush(BlockDriverState *bs);
|
||||
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
|
||||
void bdrv_close_all(void);
|
||||
void bdrv_drain(BlockDriverState *bs);
|
||||
void coroutine_fn bdrv_co_drain(BlockDriverState *bs);
|
||||
void bdrv_drain_all(void);
|
||||
|
||||
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
|
||||
|
@@ -369,6 +369,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets,
|
||||
const char *oem_id, const char *oem_table_id);
|
||||
|
||||
int
|
||||
build_append_named_dword(GArray *array, const char *name_format, ...);
|
||||
build_append_named_dword(GArray *array, const char *name_format, ...)
|
||||
GCC_FMT_ATTR(2, 3);
|
||||
|
||||
#endif
|
||||
|
@@ -108,7 +108,8 @@ struct MachineClass {
|
||||
no_cdrom:1,
|
||||
no_sdcard:1,
|
||||
has_dynamic_sysbus:1,
|
||||
pci_allow_0_address:1;
|
||||
pci_allow_0_address:1,
|
||||
legacy_fw_cfg_order:1;
|
||||
int is_default;
|
||||
const char *default_machine_opts;
|
||||
const char *default_boot_order;
|
||||
|
@@ -128,6 +128,8 @@ int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
||||
size_t romsize, hwaddr addr);
|
||||
int rom_check_and_register_reset(void);
|
||||
void rom_set_fw(FWCfgState *f);
|
||||
void rom_set_order_override(int order);
|
||||
void rom_reset_order_override(void);
|
||||
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
|
||||
void *rom_ptr(hwaddr addr);
|
||||
void hmp_info_roms(Monitor *mon, const QDict *qdict);
|
||||
|
@@ -11,6 +11,14 @@ typedef struct FWCfgFile {
|
||||
char name[FW_CFG_MAX_FILE_PATH];
|
||||
} FWCfgFile;
|
||||
|
||||
#define FW_CFG_ORDER_OVERRIDE_VGA 70
|
||||
#define FW_CFG_ORDER_OVERRIDE_NIC 80
|
||||
#define FW_CFG_ORDER_OVERRIDE_USER 100
|
||||
#define FW_CFG_ORDER_OVERRIDE_DEVICE 110
|
||||
|
||||
void fw_cfg_set_order_override(FWCfgState *fw_cfg, int order);
|
||||
void fw_cfg_reset_order_override(FWCfgState *fw_cfg);
|
||||
|
||||
typedef struct FWCfgFiles {
|
||||
uint32_t count;
|
||||
FWCfgFile f[];
|
||||
|
@@ -53,6 +53,7 @@ typedef struct VirtIOBlock {
|
||||
unsigned short sector_mask;
|
||||
bool original_wce;
|
||||
VMChangeStateEntry *change;
|
||||
bool dataplane_disabled;
|
||||
bool dataplane_started;
|
||||
struct VirtIOBlockDataPlane *dataplane;
|
||||
} VirtIOBlock;
|
||||
@@ -85,4 +86,6 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb);
|
||||
|
||||
void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb);
|
||||
|
||||
void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);
|
||||
|
||||
#endif
|
||||
|
@@ -13,20 +13,6 @@ typedef struct virtio_input_absinfo virtio_input_absinfo;
|
||||
typedef struct virtio_input_config virtio_input_config;
|
||||
typedef struct virtio_input_event virtio_input_event;
|
||||
|
||||
#if defined(HOST_WORDS_BIGENDIAN)
|
||||
# define const_le32(_x) \
|
||||
(((_x & 0x000000ffU) << 24) | \
|
||||
((_x & 0x0000ff00U) << 8) | \
|
||||
((_x & 0x00ff0000U) >> 8) | \
|
||||
((_x & 0xff000000U) >> 24))
|
||||
# define const_le16(_x) \
|
||||
(((_x & 0x00ff) << 8) | \
|
||||
((_x & 0xff00) >> 8))
|
||||
#else
|
||||
# define const_le32(_x) (_x)
|
||||
# define const_le16(_x) (_x)
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* qemu internals */
|
||||
|
||||
@@ -111,6 +97,9 @@ struct VirtIOInputHost {
|
||||
void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event);
|
||||
void virtio_input_init_config(VirtIOInput *vinput,
|
||||
virtio_input_config *config);
|
||||
virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
|
||||
uint8_t select,
|
||||
uint8_t subsel);
|
||||
void virtio_input_add_config(VirtIOInput *vinput,
|
||||
virtio_input_config *config);
|
||||
void virtio_input_idstr_config(VirtIOInput *vinput,
|
||||
|
@@ -91,7 +91,6 @@ typedef struct VirtIOSCSI {
|
||||
bool dataplane_started;
|
||||
bool dataplane_starting;
|
||||
bool dataplane_stopping;
|
||||
bool dataplane_disabled;
|
||||
bool dataplane_fenced;
|
||||
Error *blocker;
|
||||
uint32_t host_features;
|
||||
@@ -140,9 +139,9 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
|
||||
HandleOutput cmd);
|
||||
|
||||
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp);
|
||||
void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
||||
bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
||||
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
||||
void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq);
|
||||
void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq);
|
||||
void virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq);
|
||||
void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req);
|
||||
void virtio_scsi_free_req(VirtIOSCSIReq *req);
|
||||
void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
|
||||
|
@@ -251,8 +251,8 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
|
||||
void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
|
||||
bool set_handler);
|
||||
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
||||
bool assign, bool set_handler);
|
||||
void virtio_queue_notify_vq(VirtQueue *vq);
|
||||
void (*fn)(VirtIODevice *,
|
||||
VirtQueue *));
|
||||
void virtio_irq(VirtQueue *vq);
|
||||
VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
|
||||
VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
|
||||
|
@@ -125,6 +125,25 @@ static inline uint32_t qemu_bswap_len(uint32_t value, int len)
|
||||
return bswap32(value) >> (32 - 8 * len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as cpu_to_le{16,23}, except that gcc will figure the result is
|
||||
* a compile-time constant if you pass in a constant. So this can be
|
||||
* used to initialize static variables.
|
||||
*/
|
||||
#if defined(HOST_WORDS_BIGENDIAN)
|
||||
# define const_le32(_x) \
|
||||
((((_x) & 0x000000ffU) << 24) | \
|
||||
(((_x) & 0x0000ff00U) << 8) | \
|
||||
(((_x) & 0x00ff0000U) >> 8) | \
|
||||
(((_x) & 0xff000000U) >> 24))
|
||||
# define const_le16(_x) \
|
||||
((((_x) & 0x00ff) << 8) | \
|
||||
(((_x) & 0xff00) >> 8))
|
||||
#else
|
||||
# define const_le32(_x) (_x)
|
||||
# define const_le16(_x) (_x)
|
||||
#endif
|
||||
|
||||
/* Unions for reinterpreting between floats and integers. */
|
||||
|
||||
typedef union {
|
||||
|
@@ -234,6 +234,7 @@ DisplayState *init_displaystate(void);
|
||||
DisplaySurface *qemu_create_displaysurface_from(int width, int height,
|
||||
pixman_format_code_t format,
|
||||
int linesize, uint8_t *data);
|
||||
DisplaySurface *qemu_create_displaysurface_pixman(pixman_image_t *image);
|
||||
DisplaySurface *qemu_create_displaysurface_guestmem(int width, int height,
|
||||
pixman_format_code_t format,
|
||||
int linesize,
|
||||
|
63
nbd/client.c
63
nbd/client.c
@@ -73,16 +73,46 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
|
||||
*/
|
||||
|
||||
|
||||
static int nbd_handle_reply_err(uint32_t opt, uint32_t type, Error **errp)
|
||||
/* If type represents success, return 1 without further action.
|
||||
* If type represents an error reply, consume the rest of the packet on ioc.
|
||||
* Then return 0 for unsupported (so the client can fall back to
|
||||
* other approaches), or -1 with errp set for other errors.
|
||||
*/
|
||||
static int nbd_handle_reply_err(QIOChannel *ioc, uint32_t opt, uint32_t type,
|
||||
Error **errp)
|
||||
{
|
||||
uint32_t len;
|
||||
char *msg = NULL;
|
||||
int result = -1;
|
||||
|
||||
if (!(type & (1 << 31))) {
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) {
|
||||
error_setg(errp, "failed to read option length");
|
||||
return -1;
|
||||
}
|
||||
len = be32_to_cpu(len);
|
||||
if (len) {
|
||||
if (len > NBD_MAX_BUFFER_SIZE) {
|
||||
error_setg(errp, "server's error message is too long");
|
||||
goto cleanup;
|
||||
}
|
||||
msg = g_malloc(len + 1);
|
||||
if (read_sync(ioc, msg, len) != len) {
|
||||
error_setg(errp, "failed to read option error message");
|
||||
goto cleanup;
|
||||
}
|
||||
msg[len] = '\0';
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case NBD_REP_ERR_UNSUP:
|
||||
error_setg(errp, "Unsupported option type %x", opt);
|
||||
break;
|
||||
TRACE("server doesn't understand request %d, attempting fallback",
|
||||
opt);
|
||||
result = 0;
|
||||
goto cleanup;
|
||||
|
||||
case NBD_REP_ERR_POLICY:
|
||||
error_setg(errp, "Denied by server for option %x", opt);
|
||||
@@ -101,7 +131,13 @@ static int nbd_handle_reply_err(uint32_t opt, uint32_t type, Error **errp)
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
if (msg) {
|
||||
error_append_hint(errp, "%s\n", msg);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_free(msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
|
||||
@@ -111,6 +147,7 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
|
||||
uint32_t type;
|
||||
uint32_t len;
|
||||
uint32_t namelen;
|
||||
int error;
|
||||
|
||||
*name = NULL;
|
||||
if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
|
||||
@@ -138,11 +175,9 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
|
||||
return -1;
|
||||
}
|
||||
type = be32_to_cpu(type);
|
||||
if (type == NBD_REP_ERR_UNSUP) {
|
||||
return 0;
|
||||
}
|
||||
if (nbd_handle_reply_err(opt, type, errp) < 0) {
|
||||
return -1;
|
||||
error = nbd_handle_reply_err(ioc, opt, type, errp);
|
||||
if (error <= 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) {
|
||||
@@ -628,16 +663,16 @@ ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request)
|
||||
uint8_t buf[NBD_REQUEST_SIZE];
|
||||
ssize_t ret;
|
||||
|
||||
TRACE("Sending request to server: "
|
||||
"{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}",
|
||||
request->from, request->len, request->handle, request->type);
|
||||
|
||||
cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
|
||||
cpu_to_be32w((uint32_t*)(buf + 4), request->type);
|
||||
cpu_to_be64w((uint64_t*)(buf + 8), request->handle);
|
||||
cpu_to_be64w((uint64_t*)(buf + 16), request->from);
|
||||
cpu_to_be32w((uint32_t*)(buf + 24), request->len);
|
||||
|
||||
TRACE("Sending request to server: "
|
||||
"{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}",
|
||||
request->from, request->len, request->handle, request->type);
|
||||
|
||||
ret = write_sync(ioc, buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
@@ -50,9 +50,12 @@ ssize_t nbd_wr_syncv(QIOChannel *ioc,
|
||||
* qio_channel_yield() that works with AIO contexts
|
||||
* and consider using that in this branch */
|
||||
qemu_coroutine_yield();
|
||||
} else {
|
||||
} else if (done) {
|
||||
/* XXX this is needed by nbd_reply_ready. */
|
||||
qio_channel_wait(ioc,
|
||||
do_read ? G_IO_IN : G_IO_OUT);
|
||||
} else {
|
||||
return -EAGAIN;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@@ -33,18 +33,21 @@
|
||||
/* #define DEBUG_NBD */
|
||||
|
||||
#ifdef DEBUG_NBD
|
||||
#define TRACE(msg, ...) do { \
|
||||
LOG(msg, ## __VA_ARGS__); \
|
||||
} while(0)
|
||||
#define DEBUG_NBD_PRINT 1
|
||||
#else
|
||||
#define TRACE(msg, ...) \
|
||||
do { } while (0)
|
||||
#define DEBUG_NBD_PRINT 0
|
||||
#endif
|
||||
|
||||
#define TRACE(msg, ...) do { \
|
||||
if (DEBUG_NBD_PRINT) { \
|
||||
LOG(msg, ## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG(msg, ...) do { \
|
||||
fprintf(stderr, "%s:%s():L%d: " msg "\n", \
|
||||
__FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
/* This is all part of the "official" NBD API.
|
||||
*
|
||||
|
11
nbd/server.c
11
nbd/server.c
@@ -26,6 +26,7 @@ static int system_errno_to_nbd_errno(int err)
|
||||
case 0:
|
||||
return NBD_SUCCESS;
|
||||
case EPERM:
|
||||
case EROFS:
|
||||
return NBD_EPERM;
|
||||
case EIO:
|
||||
return NBD_EIO;
|
||||
@@ -482,9 +483,12 @@ static int nbd_negotiate_options(NBDClient *client)
|
||||
return -EINVAL;
|
||||
default:
|
||||
TRACE("Unsupported option 0x%x", clientflags);
|
||||
if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
|
||||
return -EIO;
|
||||
}
|
||||
nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_UNSUP,
|
||||
clientflags);
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@@ -655,6 +659,9 @@ static ssize_t nbd_send_reply(QIOChannel *ioc, struct nbd_reply *reply)
|
||||
|
||||
reply->error = system_errno_to_nbd_errno(reply->error);
|
||||
|
||||
TRACE("Sending response to client: { .error = %d, handle = %" PRIu64 " }",
|
||||
reply->error, reply->handle);
|
||||
|
||||
/* Reply
|
||||
[ 0 .. 3] magic (NBD_REPLY_MAGIC)
|
||||
[ 4 .. 7] error (0 == no error)
|
||||
@@ -664,8 +671,6 @@ static ssize_t nbd_send_reply(QIOChannel *ioc, struct nbd_reply *reply)
|
||||
stl_be_p(buf + 4, reply->error);
|
||||
stq_be_p(buf + 8, reply->handle);
|
||||
|
||||
TRACE("Sending response to client");
|
||||
|
||||
ret = write_sync(ioc, buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
@@ -164,7 +164,7 @@ static void netfilter_set_status(Object *obj, const char *str, Error **errp)
|
||||
return;
|
||||
}
|
||||
nf->on = !nf->on;
|
||||
if (nfc->status_changed) {
|
||||
if (nf->netdev && nfc->status_changed) {
|
||||
nfc->status_changed(nf, errp);
|
||||
}
|
||||
}
|
||||
|
44
net/net.c
44
net/net.c
@@ -81,34 +81,6 @@ int default_net = 1;
|
||||
/***********************************************************/
|
||||
/* network device redirectors */
|
||||
|
||||
#if defined(DEBUG_NET)
|
||||
static void hex_dump(FILE *f, const uint8_t *buf, int size)
|
||||
{
|
||||
int len, i, j, c;
|
||||
|
||||
for(i=0;i<size;i+=16) {
|
||||
len = size - i;
|
||||
if (len > 16)
|
||||
len = 16;
|
||||
fprintf(f, "%08x ", i);
|
||||
for(j=0;j<16;j++) {
|
||||
if (j < len)
|
||||
fprintf(f, " %02x", buf[i+j]);
|
||||
else
|
||||
fprintf(f, " ");
|
||||
}
|
||||
fprintf(f, " ");
|
||||
for(j=0;j<len;j++) {
|
||||
c = buf[i+j];
|
||||
if (c < ' ' || c > '~')
|
||||
c = '.';
|
||||
fprintf(f, "%c", c);
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
|
||||
{
|
||||
const char *p, *p1;
|
||||
@@ -664,7 +636,7 @@ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
|
||||
|
||||
#ifdef DEBUG_NET
|
||||
printf("qemu_send_packet_async:\n");
|
||||
hex_dump(stdout, buf, size);
|
||||
qemu_hexdump((const char *)buf, stdout, "net", size);
|
||||
#endif
|
||||
|
||||
if (sender->link_down || !sender->peer) {
|
||||
@@ -711,23 +683,28 @@ ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
|
||||
static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov,
|
||||
int iovcnt, unsigned flags)
|
||||
{
|
||||
uint8_t buf[NET_BUFSIZE];
|
||||
uint8_t *buf = NULL;
|
||||
uint8_t *buffer;
|
||||
size_t offset;
|
||||
ssize_t ret;
|
||||
|
||||
if (iovcnt == 1) {
|
||||
buffer = iov[0].iov_base;
|
||||
offset = iov[0].iov_len;
|
||||
} else {
|
||||
buf = g_new(uint8_t, NET_BUFSIZE);
|
||||
buffer = buf;
|
||||
offset = iov_to_buf(iov, iovcnt, 0, buf, sizeof(buf));
|
||||
offset = iov_to_buf(iov, iovcnt, 0, buf, NET_BUFSIZE);
|
||||
}
|
||||
|
||||
if (flags & QEMU_NET_PACKET_FLAG_RAW && nc->info->receive_raw) {
|
||||
return nc->info->receive_raw(nc, buffer, offset);
|
||||
ret = nc->info->receive_raw(nc, buffer, offset);
|
||||
} else {
|
||||
return nc->info->receive(nc, buffer, offset);
|
||||
ret = nc->info->receive(nc, buffer, offset);
|
||||
}
|
||||
|
||||
g_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t qemu_deliver_packet_iov(NetClientState *sender,
|
||||
@@ -1100,6 +1077,7 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error **errp)
|
||||
}
|
||||
|
||||
error_propagate(errp, err);
|
||||
opts_visitor_cleanup(ov);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "block/block_int.h"
|
||||
#include "block/blockjob.h"
|
||||
#include "block/qapi.h"
|
||||
#include "crypto/init.h"
|
||||
#include <getopt.h>
|
||||
|
||||
#define QEMU_IMG_VERSION "qemu-img version " QEMU_VERSION QEMU_PKGVERSION \
|
||||
@@ -256,7 +257,7 @@ static BlockBackend *img_open_opts(const char *optstr,
|
||||
options = qemu_opts_to_qdict(opts, NULL);
|
||||
blk = blk_new_open(NULL, NULL, options, flags, &local_err);
|
||||
if (!blk) {
|
||||
error_reportf_err(local_err, "Could not open '%s'", optstr);
|
||||
error_reportf_err(local_err, "Could not open '%s': ", optstr);
|
||||
return NULL;
|
||||
}
|
||||
blk_set_enable_write_cache(blk, !writethrough);
|
||||
@@ -3486,6 +3487,11 @@ int main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (qcrypto_init(&local_error) < 0) {
|
||||
error_reportf_err(local_error, "cannot initialize crypto: ");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
module_call_init(MODULE_INIT_QOM);
|
||||
bdrv_init();
|
||||
if (argc < 2) {
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "block/block_int.h"
|
||||
#include "trace/control.h"
|
||||
#include "crypto/init.h"
|
||||
|
||||
#define CMD_NOFILE_OK 0x01
|
||||
|
||||
@@ -443,6 +444,11 @@ int main(int argc, char **argv)
|
||||
progname = basename(argv[0]);
|
||||
qemu_init_exec_dir(argv[0]);
|
||||
|
||||
if (qcrypto_init(&local_error) < 0) {
|
||||
error_reportf_err(local_error, "cannot initialize crypto: ");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
module_call_init(MODULE_INIT_QOM);
|
||||
qemu_add_opts(&qemu_object_opts);
|
||||
bdrv_init();
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "qapi/qmp/qstring.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "io/channel-socket.h"
|
||||
#include "crypto/init.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <libgen.h>
|
||||
@@ -75,6 +76,7 @@ static void usage(const char *name)
|
||||
" -e, --shared=NUM device can be shared by NUM clients (default '1')\n"
|
||||
" -t, --persistent don't exit on the last connection\n"
|
||||
" -v, --verbose display extra debugging information\n"
|
||||
" -x, --export-name=NAME expose export by name\n"
|
||||
"\n"
|
||||
"Exposing part of the image:\n"
|
||||
" -o, --offset=OFFSET offset into the image\n"
|
||||
@@ -518,6 +520,12 @@ int main(int argc, char **argv)
|
||||
memset(&sa_sigterm, 0, sizeof(sa_sigterm));
|
||||
sa_sigterm.sa_handler = termsig_handler;
|
||||
sigaction(SIGTERM, &sa_sigterm, NULL);
|
||||
|
||||
if (qcrypto_init(&local_err) < 0) {
|
||||
error_reportf_err(local_err, "cannot initialize crypto: ");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
module_call_init(MODULE_INIT_QOM);
|
||||
qemu_add_opts(&qemu_object_opts);
|
||||
qemu_init_exec_dir(argv[0]);
|
||||
|
@@ -373,6 +373,7 @@ static gboolean guest_exec_output_watch(GIOChannel *ch,
|
||||
return true;
|
||||
|
||||
close:
|
||||
g_io_channel_shutdown(ch, true, NULL);
|
||||
g_io_channel_unref(ch);
|
||||
g_atomic_int_set(&p->closed, 1);
|
||||
return false;
|
||||
@@ -447,6 +448,7 @@ GuestExec *qmp_guest_exec(const char *path,
|
||||
g_io_channel_set_encoding(in_ch, NULL, NULL);
|
||||
g_io_channel_set_buffered(in_ch, false);
|
||||
g_io_channel_set_flags(in_ch, G_IO_FLAG_NONBLOCK, NULL);
|
||||
g_io_channel_set_close_on_unref(in_ch, true);
|
||||
g_io_add_watch(in_ch, G_IO_OUT, guest_exec_input_watch, &gei->in);
|
||||
}
|
||||
|
||||
@@ -462,6 +464,8 @@ GuestExec *qmp_guest_exec(const char *path,
|
||||
g_io_channel_set_encoding(err_ch, NULL, NULL);
|
||||
g_io_channel_set_buffered(out_ch, false);
|
||||
g_io_channel_set_buffered(err_ch, false);
|
||||
g_io_channel_set_close_on_unref(out_ch, true);
|
||||
g_io_channel_set_close_on_unref(err_ch, true);
|
||||
g_io_add_watch(out_ch, G_IO_IN | G_IO_HUP,
|
||||
guest_exec_output_watch, &gei->out);
|
||||
g_io_add_watch(err_ch, G_IO_IN | G_IO_HUP,
|
||||
|
@@ -96,7 +96,7 @@
|
||||
<File Id="gspawn-win32-helper-console.exe" Name="gspawn-win32-helper-console.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper-console.exe" KeyPath="yes" DiskId="1"/>
|
||||
</Component>
|
||||
<Component Id="gspawn-helper" Guid="{CD67A5A3-2DB1-4DA1-A67A-8D71E797B466}">
|
||||
<File Id="gspawn-win32-helper.exe" Name="gspawn-win32-helper.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper.exe" KeyPath="yes" DiskId="1"/>
|
||||
<File Id="gspawn-win32-helper.exe" Name="gspawn-win32-helper.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper-console.exe" KeyPath="yes" DiskId="1"/>
|
||||
</Component>
|
||||
<?endif?>
|
||||
<?if $(var.Arch) = "64"?>
|
||||
@@ -104,7 +104,7 @@
|
||||
<File Id="gspawn-win64-helper-console.exe" Name="gspawn-win64-helper-console.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper-console.exe" KeyPath="yes" DiskId="1"/>
|
||||
</Component>
|
||||
<Component Id="gspawn-helper" Guid="{D201AD22-1846-4E4F-B6E1-C7A908ED2457}">
|
||||
<File Id="gspawn-win64-helper.exe" Name="gspawn-win64-helper.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper.exe" KeyPath="yes" DiskId="1"/>
|
||||
<File Id="gspawn-win64-helper.exe" Name="gspawn-win64-helper.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper-console.exe" KeyPath="yes" DiskId="1"/>
|
||||
</Component>
|
||||
<?endif?>
|
||||
<Component Id="iconv" Guid="{35EE3558-D34B-4F0A-B8BD-430FF0775246}">
|
||||
|
@@ -534,7 +534,12 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
|
||||
* test for G_IO_IN below if this succeeds
|
||||
*/
|
||||
if (revents & G_IO_PRI) {
|
||||
sorecvoob(so);
|
||||
ret = sorecvoob(so);
|
||||
if (ret < 0) {
|
||||
/* Socket error might have resulted in the socket being
|
||||
* removed, do not try to do anything more with it. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check sockets for reading
|
||||
@@ -553,6 +558,11 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
|
||||
if (ret > 0) {
|
||||
tcp_output(sototcpcb(so));
|
||||
}
|
||||
if (ret < 0) {
|
||||
/* Socket error might have resulted in the socket being
|
||||
* removed, do not try to do anything more with it. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -176,9 +176,24 @@ soread(struct socket *so)
|
||||
if (nn < 0 && (errno == EINTR || errno == EAGAIN))
|
||||
return 0;
|
||||
else {
|
||||
int err;
|
||||
socklen_t slen = sizeof err;
|
||||
|
||||
err = errno;
|
||||
if (nn == 0) {
|
||||
getsockopt(so->s, SOL_SOCKET, SO_ERROR,
|
||||
&err, &slen);
|
||||
}
|
||||
|
||||
DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
|
||||
sofcantrcvmore(so);
|
||||
tcp_sockclosed(sototcpcb(so));
|
||||
|
||||
if (err == ECONNRESET || err == ECONNREFUSED
|
||||
|| err == ENOTCONN || err == EPIPE) {
|
||||
tcp_drop(sototcpcb(so), err);
|
||||
} else {
|
||||
tcp_sockclosed(sototcpcb(so));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -260,10 +275,11 @@ err:
|
||||
* so when OOB data arrives, we soread() it and everything
|
||||
* in the send buffer is sent as urgent data
|
||||
*/
|
||||
void
|
||||
int
|
||||
sorecvoob(struct socket *so)
|
||||
{
|
||||
struct tcpcb *tp = sototcpcb(so);
|
||||
int ret;
|
||||
|
||||
DEBUG_CALL("sorecvoob");
|
||||
DEBUG_ARG("so = %p", so);
|
||||
@@ -276,11 +292,15 @@ sorecvoob(struct socket *so)
|
||||
* urgent data, or the read() doesn't return all the
|
||||
* urgent data.
|
||||
*/
|
||||
soread(so);
|
||||
tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
|
||||
tp->t_force = 1;
|
||||
tcp_output(tp);
|
||||
tp->t_force = 0;
|
||||
ret = soread(so);
|
||||
if (ret > 0) {
|
||||
tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
|
||||
tp->t_force = 1;
|
||||
tcp_output(tp);
|
||||
tp->t_force = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -127,7 +127,7 @@ struct socket *solookup(struct socket **, struct socket *,
|
||||
struct socket *socreate(Slirp *);
|
||||
void sofree(struct socket *);
|
||||
int soread(struct socket *);
|
||||
void sorecvoob(struct socket *);
|
||||
int sorecvoob(struct socket *);
|
||||
int sosendoob(struct socket *);
|
||||
int sowrite(struct socket *);
|
||||
void sorecvfrom(struct socket *);
|
||||
|
@@ -725,6 +725,12 @@ findso:
|
||||
so->so_ti = ti;
|
||||
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
|
||||
tp->t_state = TCPS_SYN_RECEIVED;
|
||||
/*
|
||||
* Initialize receive sequence numbers now so that we can send a
|
||||
* valid RST if the remote end rejects our connection.
|
||||
*/
|
||||
tp->irs = ti->ti_seq;
|
||||
tcp_rcvseqinit(tp);
|
||||
tcp_template(tp);
|
||||
}
|
||||
return;
|
||||
|
@@ -356,6 +356,10 @@ tcp_sockclosed(struct tcpcb *tp)
|
||||
DEBUG_CALL("tcp_sockclosed");
|
||||
DEBUG_ARG("tp = %p", tp);
|
||||
|
||||
if (!tp) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (tp->t_state) {
|
||||
|
||||
case TCPS_CLOSED:
|
||||
@@ -374,8 +378,7 @@ tcp_sockclosed(struct tcpcb *tp)
|
||||
tp->t_state = TCPS_LAST_ACK;
|
||||
break;
|
||||
}
|
||||
if (tp)
|
||||
tcp_output(tp);
|
||||
tcp_output(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -919,29 +919,31 @@ do_check_protect_pse36:
|
||||
!((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) {
|
||||
prot |= PAGE_EXEC;
|
||||
}
|
||||
|
||||
if ((prot & (1 << is_write1)) == 0) {
|
||||
goto do_fault_protect;
|
||||
}
|
||||
|
||||
if ((env->cr[4] & CR4_PKE_MASK) && (env->hflags & HF_LMA_MASK) &&
|
||||
(ptep & PG_USER_MASK) && env->pkru) {
|
||||
uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT;
|
||||
uint32_t pkru_ad = (env->pkru >> pk * 2) & 1;
|
||||
uint32_t pkru_wd = (env->pkru >> pk * 2) & 2;
|
||||
uint32_t pkru_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||
|
||||
if (pkru_ad) {
|
||||
prot &= ~(PAGE_READ | PAGE_WRITE);
|
||||
pkru_prot &= ~(PAGE_READ | PAGE_WRITE);
|
||||
} else if (pkru_wd && (is_user || env->cr[0] & CR0_WP_MASK)) {
|
||||
prot &= ~PAGE_WRITE;
|
||||
pkru_prot &= ~PAGE_WRITE;
|
||||
}
|
||||
if ((prot & (1 << is_write1)) == 0) {
|
||||
|
||||
prot &= pkru_prot;
|
||||
if ((pkru_prot & (1 << is_write1)) == 0) {
|
||||
assert(is_write1 != 2);
|
||||
error_code |= PG_ERROR_PK_MASK;
|
||||
goto do_fault_protect;
|
||||
}
|
||||
}
|
||||
|
||||
if ((prot & (1 << is_write1)) == 0) {
|
||||
goto do_fault_protect;
|
||||
}
|
||||
|
||||
/* yes, it can! */
|
||||
is_dirty = is_write && !(pte & PG_DIRTY_MASK);
|
||||
if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
|
||||
|
@@ -4670,7 +4670,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
|
||||
TCGv r_const;
|
||||
|
||||
gen_address_mask(dc, cpu_addr);
|
||||
tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
|
||||
tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
|
||||
r_const = tcg_const_tl(0xff);
|
||||
tcg_gen_qemu_st8(r_const, cpu_addr, dc->mem_idx);
|
||||
tcg_temp_free(r_const);
|
||||
|
41
tci.c
41
tci.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Tiny Code Interpreter for QEMU
|
||||
*
|
||||
* Copyright (c) 2009, 2011 Stefan Weil
|
||||
* Copyright (c) 2009, 2011, 2016 Stefan Weil
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,9 +19,12 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
/* Defining NDEBUG disables assertions (which makes the code faster). */
|
||||
#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
|
||||
# define NDEBUG
|
||||
/* Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
|
||||
* Without assertions, the interpreter runs much faster. */
|
||||
#if defined(CONFIG_DEBUG_TCG)
|
||||
# define tci_assert(cond) assert(cond)
|
||||
#else
|
||||
# define tci_assert(cond) ((void)0)
|
||||
#endif
|
||||
|
||||
#include "qemu-common.h"
|
||||
@@ -56,7 +59,7 @@ static tcg_target_ulong tci_reg[TCG_TARGET_NB_REGS];
|
||||
|
||||
static tcg_target_ulong tci_read_reg(TCGReg index)
|
||||
{
|
||||
assert(index < ARRAY_SIZE(tci_reg));
|
||||
tci_assert(index < ARRAY_SIZE(tci_reg));
|
||||
return tci_reg[index];
|
||||
}
|
||||
|
||||
@@ -105,9 +108,9 @@ static uint64_t tci_read_reg64(TCGReg index)
|
||||
|
||||
static void tci_write_reg(TCGReg index, tcg_target_ulong value)
|
||||
{
|
||||
assert(index < ARRAY_SIZE(tci_reg));
|
||||
assert(index != TCG_AREG0);
|
||||
assert(index != TCG_REG_CALL_STACK);
|
||||
tci_assert(index < ARRAY_SIZE(tci_reg));
|
||||
tci_assert(index != TCG_AREG0);
|
||||
tci_assert(index != TCG_REG_CALL_STACK);
|
||||
tci_reg[index] = value;
|
||||
}
|
||||
|
||||
@@ -325,7 +328,7 @@ static uint64_t tci_read_ri64(uint8_t **tb_ptr)
|
||||
static tcg_target_ulong tci_read_label(uint8_t **tb_ptr)
|
||||
{
|
||||
tcg_target_ulong label = tci_read_i(tb_ptr);
|
||||
assert(label != 0);
|
||||
tci_assert(label != 0);
|
||||
return label;
|
||||
}
|
||||
|
||||
@@ -468,11 +471,11 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
|
||||
tci_reg[TCG_AREG0] = (tcg_target_ulong)env;
|
||||
tci_reg[TCG_REG_CALL_STACK] = sp_value;
|
||||
assert(tb_ptr);
|
||||
tci_assert(tb_ptr);
|
||||
|
||||
for (;;) {
|
||||
TCGOpcode opc = tb_ptr[0];
|
||||
#if !defined(NDEBUG)
|
||||
#if defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
|
||||
uint8_t op_size = tb_ptr[1];
|
||||
uint8_t *old_code_ptr = tb_ptr;
|
||||
#endif
|
||||
@@ -525,7 +528,7 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
break;
|
||||
case INDEX_op_br:
|
||||
label = tci_read_label(&tb_ptr);
|
||||
assert(tb_ptr == old_code_ptr + op_size);
|
||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
||||
tb_ptr = (uint8_t *)label;
|
||||
continue;
|
||||
case INDEX_op_setcond_i32:
|
||||
@@ -600,7 +603,7 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
t0 = tci_read_r32(&tb_ptr);
|
||||
t1 = tci_read_r(&tb_ptr);
|
||||
t2 = tci_read_s32(&tb_ptr);
|
||||
assert(t1 != sp_value || (int32_t)t2 < 0);
|
||||
tci_assert(t1 != sp_value || (int32_t)t2 < 0);
|
||||
*(uint32_t *)(t1 + t2) = t0;
|
||||
break;
|
||||
|
||||
@@ -725,7 +728,7 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
condition = *tb_ptr++;
|
||||
label = tci_read_label(&tb_ptr);
|
||||
if (tci_compare32(t0, t1, condition)) {
|
||||
assert(tb_ptr == old_code_ptr + op_size);
|
||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
||||
tb_ptr = (uint8_t *)label;
|
||||
continue;
|
||||
}
|
||||
@@ -751,7 +754,7 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
condition = *tb_ptr++;
|
||||
label = tci_read_label(&tb_ptr);
|
||||
if (tci_compare64(tmp64, v64, condition)) {
|
||||
assert(tb_ptr == old_code_ptr + op_size);
|
||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
||||
tb_ptr = (uint8_t *)label;
|
||||
continue;
|
||||
}
|
||||
@@ -885,7 +888,7 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
t0 = tci_read_r64(&tb_ptr);
|
||||
t1 = tci_read_r(&tb_ptr);
|
||||
t2 = tci_read_s32(&tb_ptr);
|
||||
assert(t1 != sp_value || (int32_t)t2 < 0);
|
||||
tci_assert(t1 != sp_value || (int32_t)t2 < 0);
|
||||
*(uint64_t *)(t1 + t2) = t0;
|
||||
break;
|
||||
|
||||
@@ -992,7 +995,7 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
condition = *tb_ptr++;
|
||||
label = tci_read_label(&tb_ptr);
|
||||
if (tci_compare64(t0, t1, condition)) {
|
||||
assert(tb_ptr == old_code_ptr + op_size);
|
||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
||||
tb_ptr = (uint8_t *)label;
|
||||
continue;
|
||||
}
|
||||
@@ -1087,7 +1090,7 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
break;
|
||||
case INDEX_op_goto_tb:
|
||||
t0 = tci_read_i32(&tb_ptr);
|
||||
assert(tb_ptr == old_code_ptr + op_size);
|
||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
||||
tb_ptr += (int32_t)t0;
|
||||
continue;
|
||||
case INDEX_op_qemu_ld_i32:
|
||||
@@ -1234,7 +1237,7 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
TODO();
|
||||
break;
|
||||
}
|
||||
assert(tb_ptr == old_code_ptr + op_size);
|
||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
||||
}
|
||||
exit:
|
||||
return next_tb;
|
||||
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@@ -39,6 +39,7 @@ test-io-channel-file.txt
|
||||
test-io-channel-socket
|
||||
test-io-channel-tls
|
||||
test-io-task
|
||||
test-logging
|
||||
test-mul64
|
||||
test-opts-visitor
|
||||
test-qapi-event.[ch]
|
||||
|
@@ -83,7 +83,7 @@ check-unit-y += tests/test-crypto-cipher$(EXESUF)
|
||||
check-unit-y += tests/test-crypto-secret$(EXESUF)
|
||||
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
|
||||
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlssession$(EXESUF)
|
||||
check-unit-$(CONFIG_LINUX) += tests/test-qga$(EXESUF)
|
||||
#check-unit-$(CONFIG_LINUX) += tests/test-qga$(EXESUF)
|
||||
check-unit-y += tests/test-timed-average$(EXESUF)
|
||||
check-unit-y += tests/test-io-task$(EXESUF)
|
||||
check-unit-y += tests/test-io-channel-socket$(EXESUF)
|
||||
|
@@ -432,7 +432,7 @@ static bool load_asl(GArray *sdts, AcpiSdtTable *sdt)
|
||||
|
||||
#define COMMENT_END "*/"
|
||||
#define DEF_BLOCK "DefinitionBlock ("
|
||||
#define BLOCK_NAME_END ".aml"
|
||||
#define BLOCK_NAME_END ","
|
||||
|
||||
static GString *normalize_asl(gchar *asl_code)
|
||||
{
|
||||
|
@@ -14,6 +14,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_update; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -21,6 +23,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_update; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -38,6 +42,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_update; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -45,6 +51,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_update; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -70,7 +78,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
Event: l2_load; errno: 5; imm: off; once: off; write
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
read failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -78,7 +90,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
Event: l2_load; errno: 5; imm: off; once: off; write -b
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
read failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -102,7 +118,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
Event: l2_load; errno: 28; imm: off; once: off; write
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
read failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -110,7 +130,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
Event: l2_load; errno: 28; imm: off; once: off; write -b
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
read failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -118,20 +142,18 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
Event: l2_update; errno: 5; imm: off; once: on; write
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 5; imm: off; once: on; write -b
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
@@ -140,6 +162,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
@@ -150,20 +174,18 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
Event: l2_update; errno: 28; imm: off; once: on; write
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 28; imm: off; once: on; write -b
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
@@ -172,6 +194,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
@@ -190,11 +214,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_alloc_write; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_alloc_write; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -212,11 +240,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_alloc_write; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_alloc_write; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -234,11 +266,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: write_aio; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: write_aio; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -254,11 +290,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: write_aio; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: write_aio; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -274,11 +314,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_load; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_load; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -294,11 +338,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_load; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_load; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -314,11 +362,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -334,11 +386,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -354,11 +410,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -374,11 +434,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -394,11 +458,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: cluster_alloc; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: cluster_alloc; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -414,11 +482,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: cluster_alloc; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: cluster_alloc; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
|
||||
@@ -437,6 +509,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
55 leaked clusters were found on the image.
|
||||
@@ -444,6 +518,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
251 leaked clusters were found on the image.
|
||||
@@ -461,11 +537,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc_write; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc_write; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -481,13 +561,17 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
10 leaked clusters were found on the image.
|
||||
11 leaked clusters were found on the image.
|
||||
This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
23 leaked clusters were found on the image.
|
||||
@@ -505,13 +589,17 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
10 leaked clusters were found on the image.
|
||||
11 leaked clusters were found on the image.
|
||||
This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
23 leaked clusters were found on the image.
|
||||
@@ -529,13 +617,17 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
10 leaked clusters were found on the image.
|
||||
11 leaked clusters were found on the image.
|
||||
This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
23 leaked clusters were found on the image.
|
||||
@@ -551,6 +643,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow_alloc_table; errno: 5; imm: off; once: off
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -561,6 +655,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow_alloc_table; errno: 28; imm: off; once: off
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -571,6 +667,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow_write_table; errno: 5; imm: off; once: off
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -581,6 +679,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow_write_table; errno: 28; imm: off; once: off
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -591,6 +691,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow_activate_table; errno: 5; imm: off; once: off
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
96 leaked clusters were found on the image.
|
||||
@@ -603,6 +705,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow_activate_table; errno: 28; imm: off; once: off
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
96 leaked clusters were found on the image.
|
||||
|
@@ -145,7 +145,7 @@ QEMU X.Y.Z monitor - type 'help' for more information
|
||||
Testing: -drive driver=null-co,cache=invalid_value
|
||||
QEMU_PROG: -drive driver=null-co,cache=invalid_value: invalid cache option
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,cache=writeback,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.cache.writeback=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,cache=writeback,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K
|
||||
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
|
||||
@@ -165,7 +165,7 @@ backing-file: TEST_DIR/t.qcow2.base (file, read-only)
|
||||
Cache mode: writeback, ignore flushes
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,cache=writethrough,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.cache.writeback=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,cache=writethrough,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K
|
||||
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
|
||||
@@ -185,7 +185,7 @@ backing-file: TEST_DIR/t.qcow2.base (file, read-only)
|
||||
Cache mode: writeback, ignore flushes
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,cache=unsafe,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.cache.writeback=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,cache=unsafe,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K
|
||||
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
|
||||
@@ -205,8 +205,8 @@ backing-file: TEST_DIR/t.qcow2.base (file, read-only)
|
||||
Cache mode: writeback, ignore flushes
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.cache.writeback=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.cache.writeback=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0: invalid cache option
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0: invalid cache option
|
||||
|
||||
|
||||
=== Specifying the protocol layer ===
|
||||
|
@@ -53,7 +53,7 @@ _make_test_img $IMG_SIZE
|
||||
|
||||
case "$QEMU_DEFAULT_MACHINE" in
|
||||
s390-ccw-virtio)
|
||||
platform_parm="-no-shutdown -machine accel=kvm"
|
||||
platform_parm="-no-shutdown"
|
||||
;;
|
||||
*)
|
||||
platform_parm=""
|
||||
|
@@ -79,9 +79,6 @@ sector = "%d"
|
||||
self.assert_qmp(event, 'data/sector-num', sector)
|
||||
|
||||
def testQuorum(self):
|
||||
if not 'quorum' in iotests.qemu_img_pipe('--help'):
|
||||
return
|
||||
|
||||
# Generate an error and get an event
|
||||
self.vm.hmp_qemu_io("drive0", "aio_read %d %d" %
|
||||
(offset * sector_size, sector_size))
|
||||
@@ -139,4 +136,5 @@ class TestFifoQuorumEvents(TestQuorumEvents):
|
||||
read_pattern = 'fifo'
|
||||
|
||||
if __name__ == '__main__':
|
||||
iotests.verify_quorum()
|
||||
iotests.main(supported_fmts=["raw"])
|
||||
|
@@ -38,65 +38,34 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
. ./common.rc
|
||||
. ./common.filter
|
||||
|
||||
_supported_fmt generic
|
||||
_supported_fmt raw qcow2
|
||||
_supported_proto file
|
||||
_supported_os Linux
|
||||
|
||||
|
||||
on_disk_size()
|
||||
{
|
||||
du "$@" | sed -e 's/\t\+.*//'
|
||||
}
|
||||
|
||||
|
||||
img_size=1048576
|
||||
|
||||
|
||||
echo
|
||||
echo '=== Comparing empty image against sparse conversion ==='
|
||||
echo '=== Mapping sparse conversion ==='
|
||||
echo
|
||||
|
||||
_make_test_img $img_size
|
||||
|
||||
empty_size=$(on_disk_size "$TEST_IMG")
|
||||
|
||||
|
||||
$QEMU_IMG_PROG convert -O "$IMGFMT" -S 512 \
|
||||
"json:{ 'driver': 'null-co', 'size': $img_size, 'read-zeroes': true }" \
|
||||
"$TEST_IMG"
|
||||
|
||||
sparse_convert_size=$(on_disk_size "$TEST_IMG")
|
||||
|
||||
|
||||
if [ "$empty_size" -eq "$sparse_convert_size" ]; then
|
||||
echo 'Equal image size'
|
||||
else
|
||||
echo 'Different image size'
|
||||
fi
|
||||
$QEMU_IMG map "$TEST_IMG" | _filter_qemu_img_map
|
||||
|
||||
|
||||
echo
|
||||
echo '=== Comparing full image against non-sparse conversion ==='
|
||||
echo '=== Mapping non-sparse conversion ==='
|
||||
echo
|
||||
|
||||
_make_test_img $img_size
|
||||
$QEMU_IO -c "write 0 $img_size" "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
full_size=$(on_disk_size "$TEST_IMG")
|
||||
|
||||
|
||||
$QEMU_IMG convert -O "$IMGFMT" -S 0 \
|
||||
"json:{ 'driver': 'null-co', 'size': $img_size, 'read-zeroes': true }" \
|
||||
"$TEST_IMG"
|
||||
|
||||
non_sparse_convert_size=$(on_disk_size "$TEST_IMG")
|
||||
|
||||
|
||||
if [ "$full_size" -eq "$non_sparse_convert_size" ]; then
|
||||
echo 'Equal image size'
|
||||
else
|
||||
echo 'Different image size'
|
||||
fi
|
||||
$QEMU_IMG map "$TEST_IMG" | _filter_qemu_img_map
|
||||
|
||||
|
||||
# success, all done
|
||||
|
@@ -1,14 +1,11 @@
|
||||
QA output created by 150
|
||||
|
||||
=== Comparing empty image against sparse conversion ===
|
||||
=== Mapping sparse conversion ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
Equal image size
|
||||
Offset Length File
|
||||
|
||||
=== Comparing full image against non-sparse conversion ===
|
||||
=== Mapping non-sparse conversion ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
wrote 1048576/1048576 bytes at offset 0
|
||||
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Equal image size
|
||||
Offset Length File
|
||||
0 0x100000 TEST_DIR/t.IMGFMT
|
||||
*** done
|
||||
|
@@ -19,7 +19,6 @@
|
||||
# Control script for QA
|
||||
#
|
||||
|
||||
tmp=/tmp/$$
|
||||
status=0
|
||||
needwrap=true
|
||||
try=0
|
||||
@@ -130,6 +129,8 @@ fi
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
tmp="${TEST_DIR}"/$$
|
||||
|
||||
_wallclock()
|
||||
{
|
||||
date "+%H %M %S" | $AWK_PROG '{ print $1*3600 + $2*60 + $3 }'
|
||||
@@ -146,8 +147,8 @@ _wrapup()
|
||||
# for hangcheck ...
|
||||
# remove files that were used by hangcheck
|
||||
#
|
||||
[ -f /tmp/check.pid ] && rm -rf /tmp/check.pid
|
||||
[ -f /tmp/check.sts ] && rm -rf /tmp/check.sts
|
||||
[ -f "${TEST_DIR}"/check.pid ] && rm -rf "${TEST_DIR}"/check.pid
|
||||
[ -f "${TEST_DIR}"/check.sts ] && rm -rf "${TEST_DIR}"/check.sts
|
||||
|
||||
if $showme
|
||||
then
|
||||
@@ -197,8 +198,8 @@ END { if (NR > 0) {
|
||||
needwrap=false
|
||||
fi
|
||||
|
||||
rm -f /tmp/*.out /tmp/*.err /tmp/*.time
|
||||
rm -f /tmp/check.pid /tmp/check.sts
|
||||
rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time
|
||||
rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts
|
||||
rm -f $tmp.*
|
||||
}
|
||||
|
||||
@@ -208,16 +209,16 @@ trap "_wrapup; exit \$status" 0 1 2 3 15
|
||||
# Save pid of check in a well known place, so that hangcheck can be sure it
|
||||
# has the right pid (getting the pid from ps output is not reliable enough).
|
||||
#
|
||||
rm -rf /tmp/check.pid
|
||||
echo $$ >/tmp/check.pid
|
||||
rm -rf "${TEST_DIR}"/check.pid
|
||||
echo $$ > "${TEST_DIR}"/check.pid
|
||||
|
||||
# for hangcheck ...
|
||||
# Save the status of check in a well known place, so that hangcheck can be
|
||||
# sure to know where check is up to (getting test number from ps output is
|
||||
# not reliable enough since the trace stuff has been introduced).
|
||||
#
|
||||
rm -rf /tmp/check.sts
|
||||
echo "preamble" >/tmp/check.sts
|
||||
rm -rf "${TEST_DIR}"/check.sts
|
||||
echo "preamble" > "${TEST_DIR}"/check.sts
|
||||
|
||||
# don't leave old full output behind on a clean run
|
||||
rm -f check.full
|
||||
@@ -285,7 +286,7 @@ do
|
||||
rm -f core $seq.notrun
|
||||
|
||||
# for hangcheck ...
|
||||
echo "$seq" >/tmp/check.sts
|
||||
echo "$seq" > "${TEST_DIR}"/check.sts
|
||||
|
||||
start=`_wallclock`
|
||||
$timestamp && echo -n " ["`date "+%T"`"]"
|
||||
|
@@ -16,6 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import errno
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
@@ -28,10 +29,6 @@ import qmp
|
||||
import qtest
|
||||
import struct
|
||||
|
||||
__all__ = ['imgfmt', 'imgproto', 'test_dir' 'qemu_img', 'qemu_io',
|
||||
'VM', 'QMPTestCase', 'notrun', 'main', 'verify_image_format',
|
||||
'verify_platform', 'filter_test_dir', 'filter_win32',
|
||||
'filter_qemu_io', 'filter_chown', 'log']
|
||||
|
||||
# This will not work if arguments contain spaces but is necessary if we
|
||||
# want to support the override options that ./check supports.
|
||||
@@ -247,7 +244,8 @@ class VM(object):
|
||||
self._qmp.accept()
|
||||
self._qtest.accept()
|
||||
except:
|
||||
os.remove(self._monitor_path)
|
||||
_remove_if_exists(self._monitor_path)
|
||||
_remove_if_exists(self._qtest_path)
|
||||
raise
|
||||
|
||||
def shutdown(self):
|
||||
@@ -409,6 +407,15 @@ class QMPTestCase(unittest.TestCase):
|
||||
event = self.wait_until_completed(drive=drive)
|
||||
self.assert_qmp(event, 'data/type', 'mirror')
|
||||
|
||||
def _remove_if_exists(path):
|
||||
'''Remove file object at path if it exists'''
|
||||
try:
|
||||
os.remove(path)
|
||||
except OSError as exception:
|
||||
if exception.errno == errno.ENOENT:
|
||||
return
|
||||
raise
|
||||
|
||||
def notrun(reason):
|
||||
'''Skip this test suite'''
|
||||
# Each test in qemu-iotests has a number ("seq")
|
||||
@@ -426,6 +433,11 @@ def verify_platform(supported_oses=['linux']):
|
||||
if True not in [sys.platform.startswith(x) for x in supported_oses]:
|
||||
notrun('not suitable for this OS: %s' % sys.platform)
|
||||
|
||||
def verify_quorum():
|
||||
'''Skip test suite if quorum support is not available'''
|
||||
if 'quorum' not in qemu_img_pipe('--help'):
|
||||
notrun('quorum support missing')
|
||||
|
||||
def main(supported_fmts=[], supported_oses=['linux']):
|
||||
'''Run tests'''
|
||||
|
||||
|
@@ -1161,6 +1161,7 @@ console_select(int nr) "%d"
|
||||
console_refresh(int interval) "interval %d ms"
|
||||
displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
|
||||
displaysurface_create_from(void *display_surface, int w, int h, uint32_t format) "surface=%p, %dx%d, format 0x%x"
|
||||
displaysurface_create_pixman(void *display_surface) "surface=%p"
|
||||
displaysurface_free(void *display_surface) "surface=%p"
|
||||
displaychangelistener_register(void *dcl, const char *name) "%p [ %s ]"
|
||||
displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]"
|
||||
|
@@ -861,7 +861,8 @@ static void tb_invalidate_check(target_ulong address)
|
||||
|
||||
address &= TARGET_PAGE_MASK;
|
||||
for (i = 0; i < CODE_GEN_PHYS_HASH_SIZE; i++) {
|
||||
for (tb = tb_ctx.tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
|
||||
for (tb = tcg_ctx.tb_ctx.tb_phys_hash[i]; tb != NULL;
|
||||
tb = tb->phys_hash_next) {
|
||||
if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
|
||||
address >= tb->pc + tb->size)) {
|
||||
printf("ERROR invalidate: address=" TARGET_FMT_lx
|
||||
|
11
ui/console.c
11
ui/console.c
@@ -1292,6 +1292,17 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height,
|
||||
return surface;
|
||||
}
|
||||
|
||||
DisplaySurface *qemu_create_displaysurface_pixman(pixman_image_t *image)
|
||||
{
|
||||
DisplaySurface *surface = g_new0(DisplaySurface, 1);
|
||||
|
||||
trace_displaysurface_create_pixman(surface);
|
||||
surface->format = pixman_image_get_format(image);
|
||||
surface->image = pixman_image_ref(image);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void qemu_unmap_displaysurface_guestmem(pixman_image_t *image,
|
||||
void *unused)
|
||||
{
|
||||
|
@@ -337,7 +337,7 @@ static void input_linux_event_mouse(void *opaque)
|
||||
static void input_linux_complete(UserCreatable *uc, Error **errp)
|
||||
{
|
||||
InputLinux *il = INPUT_LINUX(uc);
|
||||
uint32_t evtmap;
|
||||
uint32_t evtmap, relmap, absmap;
|
||||
int rc, ver;
|
||||
|
||||
if (!il->evdev) {
|
||||
@@ -359,16 +359,36 @@ static void input_linux_complete(UserCreatable *uc, Error **errp)
|
||||
}
|
||||
|
||||
rc = ioctl(il->fd, EVIOCGBIT(0, sizeof(evtmap)), &evtmap);
|
||||
if (rc < 0) {
|
||||
error_setg(errp, "%s: failed to read event bits", il->evdev);
|
||||
goto err_close;
|
||||
}
|
||||
|
||||
if (evtmap & (1 << EV_REL)) {
|
||||
/* has relative axis -> assume mouse */
|
||||
rc = ioctl(il->fd, EVIOCGBIT(EV_REL, sizeof(relmap)), &relmap);
|
||||
if (rc < 0) {
|
||||
relmap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (evtmap & (1 << EV_ABS)) {
|
||||
ioctl(il->fd, EVIOCGBIT(EV_ABS, sizeof(absmap)), &absmap);
|
||||
if (rc < 0) {
|
||||
absmap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((evtmap & (1 << EV_REL)) &&
|
||||
(relmap & (1 << REL_X))) {
|
||||
/* has relative x axis -> assume mouse */
|
||||
qemu_set_fd_handler(il->fd, input_linux_event_mouse, NULL, il);
|
||||
} else if (evtmap & (1 << EV_ABS)) {
|
||||
/* has absolute axis -> not supported */
|
||||
} else if ((evtmap & (1 << EV_ABS)) &&
|
||||
(absmap & (1 << ABS_X))) {
|
||||
/* has absolute x axis -> not supported */
|
||||
error_setg(errp, "tablet/touchscreen not supported");
|
||||
goto err_close;
|
||||
} else if (evtmap & (1 << EV_KEY)) {
|
||||
/* has keys/buttons (and no axis) -> assume keyboard */
|
||||
/* has keys/buttons (and no x axis) -> assume keyboard */
|
||||
qemu_set_fd_handler(il->fd, input_linux_event_keyboard, NULL, il);
|
||||
} else {
|
||||
/* Huh? What is this? */
|
||||
|
@@ -18,21 +18,32 @@
|
||||
|
||||
void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size)
|
||||
{
|
||||
unsigned int b;
|
||||
unsigned int b, len, i, c;
|
||||
|
||||
for (b = 0; b < size; b++) {
|
||||
if ((b % 16) == 0) {
|
||||
fprintf(fp, "%s: %04x:", prefix, b);
|
||||
for (b = 0; b < size; b += 16) {
|
||||
len = size - b;
|
||||
if (len > 16) {
|
||||
len = 16;
|
||||
}
|
||||
if ((b % 4) == 0) {
|
||||
fprintf(fp, " ");
|
||||
fprintf(fp, "%s: %04x:", prefix, b);
|
||||
for (i = 0; i < 16; i++) {
|
||||
if ((i % 4) == 0) {
|
||||
fprintf(fp, " ");
|
||||
}
|
||||
if (i < len) {
|
||||
fprintf(fp, " %02x", (unsigned char)buf[b + i]);
|
||||
} else {
|
||||
fprintf(fp, " ");
|
||||
}
|
||||
}
|
||||
fprintf(fp, " %02x", (unsigned char)buf[b]);
|
||||
if ((b % 16) == 15) {
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, " ");
|
||||
for (i = 0; i < len; i++) {
|
||||
c = buf[b + i];
|
||||
if (c < ' ' || c > '~') {
|
||||
c = '.';
|
||||
}
|
||||
fprintf(fp, "%c", c);
|
||||
}
|
||||
}
|
||||
if ((b % 16) != 0) {
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
}
|
||||
|
10
vl.c
10
vl.c
@@ -2297,8 +2297,9 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
|
||||
gchar *buf;
|
||||
size_t size;
|
||||
const char *name, *file, *str;
|
||||
FWCfgState *fw_cfg = (FWCfgState *) opaque;
|
||||
|
||||
if (opaque == NULL) {
|
||||
if (fw_cfg == NULL) {
|
||||
error_report("fw_cfg device not available");
|
||||
return -1;
|
||||
}
|
||||
@@ -2332,7 +2333,10 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
fw_cfg_add_file((FWCfgState *)opaque, name, buf, size);
|
||||
/* For legacy, keep user files in a specific global order. */
|
||||
fw_cfg_set_order_override(fw_cfg, FW_CFG_ORDER_OVERRIDE_USER);
|
||||
fw_cfg_add_file(fw_cfg, name, buf, size);
|
||||
fw_cfg_reset_order_override(fw_cfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4535,10 +4539,12 @@ int main(int argc, char **argv, char **envp)
|
||||
igd_gfx_passthru();
|
||||
|
||||
/* init generic devices */
|
||||
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
|
||||
if (qemu_opts_foreach(qemu_find_opts("device"),
|
||||
device_init_func, NULL, NULL)) {
|
||||
exit(1);
|
||||
}
|
||||
rom_reset_order_override();
|
||||
|
||||
/* Did we create any drives that we failed to create a device for? */
|
||||
drive_check_orphaned();
|
||||
|
Reference in New Issue
Block a user