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; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -186,7 +186,7 @@ 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:    [                                                      ] | ||||
|   C:    [CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC] | ||||
|   B:                  [                          ] | ||||
| @@ -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,7 +99,7 @@ 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, | ||||
| virtio_input_config *virtio_input_find_config(VirtIOInput *vinput, | ||||
|                                               uint8_t select, | ||||
|                                               uint8_t subsel) | ||||
| { | ||||
| @@ -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); | ||||
|         if (!s->dataplane_fenced) { | ||||
|             return; | ||||
|         } | ||||
|     if (s->events_dropped) { | ||||
|         virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0); | ||||
|     } | ||||
|     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,25 +201,15 @@ 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]); | ||||
|         } | ||||
|         } | ||||
|     } else if (timer_fsb_route(timer)) { | ||||
|         address_space_stl_le(&address_space_memory, timer->fsb >> 32, | ||||
|                              timer->fsb & 0xffffffff, MEMTXATTRS_UNSPECIFIED, | ||||
|                              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]); | ||||
|         } | ||||
|     } 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); | ||||
|  | ||||
| 			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); | ||||
| 	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,7 +378,6 @@ tcp_sockclosed(struct tcpcb *tp) | ||||
| 		tp->t_state = TCPS_LAST_ACK; | ||||
| 		break; | ||||
| 	} | ||||
| 	if (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. | ||||
| 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. | ||||
| 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. | ||||
| 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. | ||||
| 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, "%s: %04x:", prefix, b); | ||||
|         for (i = 0; i < 16; i++) { | ||||
|             if ((i % 4) == 0) { | ||||
|                 fprintf(fp, " "); | ||||
|             } | ||||
|         fprintf(fp, " %02x", (unsigned char)buf[b]); | ||||
|         if ((b % 16) == 15) { | ||||
|             fprintf(fp, "\n"); | ||||
|             if (i < len) { | ||||
|                 fprintf(fp, " %02x", (unsigned char)buf[b + i]); | ||||
|             } else { | ||||
|                 fprintf(fp, "   "); | ||||
|             } | ||||
|         } | ||||
|     if ((b % 16) != 0) { | ||||
|         fprintf(fp, " "); | ||||
|         for (i = 0; i < len; i++) { | ||||
|             c = buf[b + i]; | ||||
|             if (c < ' ' || c > '~') { | ||||
|                 c = '.'; | ||||
|             } | ||||
|             fprintf(fp, "%c", c); | ||||
|         } | ||||
|         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