static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, unsigned *lossp, unsigned consider) { const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt); const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt); int src_color, dst_color; int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth; int ret, loss, i, nb_components; int score = INT_MAX - 1; if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE) return ~0; /* compute loss */ *lossp = loss = 0; if (dst_pix_fmt == src_pix_fmt) return INT_MAX; if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0) return ret; if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0) return ret; src_color = get_color_type(src_desc); dst_color = get_color_type(dst_desc); if (dst_pix_fmt == AV_PIX_FMT_PAL8) nb_components = FFMIN(src_desc->nb_components, 4); else nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components); for (i = 0; i < nb_components; i++) { int depth_minus1 = (dst_pix_fmt == AV_PIX_FMT_PAL8) ? 7/nb_components : (dst_desc->comp[i].depth - 1); if (src_desc->comp[i].depth - 1 > depth_minus1 && (consider & FF_LOSS_DEPTH)) { loss |= FF_LOSS_DEPTH; score -= 65536 >> depth_minus1; } } if (consider & FF_LOSS_RESOLUTION) { if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w) { loss |= FF_LOSS_RESOLUTION; score -= 256 << dst_desc->log2_chroma_w; } if (dst_desc->log2_chroma_h > src_desc->log2_chroma_h) { loss |= FF_LOSS_RESOLUTION; score -= 256 << dst_desc->log2_chroma_h; } // don't favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 0 && dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 0 ) { score += 512; } } if(consider & FF_LOSS_COLORSPACE) switch(dst_color) { case FF_COLOR_RGB: if (src_color != FF_COLOR_RGB && src_color != FF_COLOR_GRAY) loss |= FF_LOSS_COLORSPACE; break; case FF_COLOR_GRAY: if (src_color != FF_COLOR_GRAY) loss |= FF_LOSS_COLORSPACE; break; case FF_COLOR_YUV: if (src_color != FF_COLOR_YUV) loss |= FF_LOSS_COLORSPACE; break; case FF_COLOR_YUV_JPEG: if (src_color != FF_COLOR_YUV_JPEG && src_color != FF_COLOR_YUV && src_color != FF_COLOR_GRAY) loss |= FF_LOSS_COLORSPACE; break; default: /* fail safe test */ if (src_color != dst_color) loss |= FF_LOSS_COLORSPACE; break; } if(loss & FF_LOSS_COLORSPACE) score -= (nb_components * 65536) >> FFMIN(dst_desc->comp[0].depth - 1, src_desc->comp[0].depth - 1); if (dst_color == FF_COLOR_GRAY && src_color != FF_COLOR_GRAY && (consider & FF_LOSS_CHROMA)) { loss |= FF_LOSS_CHROMA; score -= 2 * 65536; } if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))) { loss |= FF_LOSS_ALPHA; score -= 65536; } if (dst_pix_fmt == AV_PIX_FMT_PAL8 && (consider & FF_LOSS_COLORQUANT) && (src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))))) { loss |= FF_LOSS_COLORQUANT; score -= 65536; } *lossp = loss; return score; }


static void pc_init1(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, int pci_enabled, const char *cpu_model) { char *filename; int ret, linux_boot, i; ram_addr_t ram_addr, bios_offset, option_rom_offset; ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; int bios_size, isa_bios_size, oprom_area_size; PCIBus *pci_bus; int piix3_devfn = -1; CPUState *env; qemu_irq *cpu_irq; qemu_irq *i8259; int index; BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BlockDriverState *fd[MAX_FD]; int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled; if (ram_size >= 0xe0000000 ) { above_4g_mem_size = ram_size - 0xe0000000; below_4g_mem_size = 0xe0000000; } else { below_4g_mem_size = ram_size; } linux_boot = (kernel_filename != NULL); /* init CPUs */ if (cpu_model == NULL) { #ifdef TARGET_X86_64 cpu_model = "qemu64"; #else cpu_model = "qemu32"; #endif } for(i = 0; i < smp_cpus; i++) { env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find x86 CPU definition\n"); exit(1); } if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) { env->cpuid_apic_id = env->cpu_index; apic_init(env); } qemu_register_reset(main_cpu_reset, 0, env); } vmport_init(); /* allocate RAM */ ram_addr = qemu_ram_alloc(0xa0000); cpu_register_physical_memory(0, 0xa0000, ram_addr); /* Allocate, even though we won't register, so we don't break the * phys_ram_base + PA assumption. This range includes vga (0xa0000 - 0xc0000), * and some bios areas, which will be registered later */ ram_addr = qemu_ram_alloc(0x100000 - 0xa0000); ram_addr = qemu_ram_alloc(below_4g_mem_size - 0x100000); cpu_register_physical_memory(0x100000, below_4g_mem_size - 0x100000, ram_addr); /* above 4giga memory allocation */ if (above_4g_mem_size > 0) { #if TARGET_PHYS_ADDR_BITS == 32 hw_error("To much RAM for 32-bit physical address"); #else ram_addr = qemu_ram_alloc(above_4g_mem_size); cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size, ram_addr); #endif } /* BIOS load */ if (bios_name == NULL) bios_name = BIOS_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = get_image_size(filename); } else { bios_size = -1; } if (bios_size <= 0 || (bios_size % 65536) != 0) { goto bios_error; } bios_offset = qemu_ram_alloc(bios_size); ret = load_image(filename, qemu_get_ram_ptr(bios_offset)); if (ret != bios_size) { bios_error: fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name); exit(1); } if (filename) { qemu_free(filename); } /* map the last 128KB of the BIOS in ISA space */ isa_bios_size = bios_size; if (isa_bios_size > (128 * 1024)) isa_bios_size = 128 * 1024; cpu_register_physical_memory(0x100000 - isa_bios_size, isa_bios_size, (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM); option_rom_offset = qemu_ram_alloc(0x20000); oprom_area_size = 0; cpu_register_physical_memory(0xc0000, 0x20000, option_rom_offset); if (using_vga) { const char *vgabios_filename; /* VGA BIOS load */ if (cirrus_vga_enabled) { vgabios_filename = VGABIOS_CIRRUS_FILENAME; } else { vgabios_filename = VGABIOS_FILENAME; } oprom_area_size = load_option_rom(vgabios_filename, 0xc0000, 0xe0000); } /* Although video roms can grow larger than 0x8000, the area between * 0xc0000 - 0xc8000 is reserved for them. It means we won't be looking * for any other kind of option rom inside this area */ if (oprom_area_size < 0x8000) oprom_area_size = 0x8000; if (linux_boot) { load_linux(0xc0000 + oprom_area_size, kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size); oprom_area_size += 2048; } for (i = 0; i < nb_option_roms; i++) { oprom_area_size += load_option_rom(option_rom[i], 0xc0000 + oprom_area_size, 0xe0000); } /* map all the bios at the top of memory */ cpu_register_physical_memory((uint32_t)(-bios_size), bios_size, bios_offset | IO_MEM_ROM); bochs_bios_init(); cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1); i8259 = i8259_init(cpu_irq[0]); ferr_irq = i8259[13]; if (pci_enabled) { pci_bus = i440fx_init(&i440fx_state, i8259); piix3_devfn = piix3_init(pci_bus, -1); } else { pci_bus = NULL; } /* init basic PC hardware */ register_ioport_write(0x80, 1, 1, ioport80_write, NULL); register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); if (cirrus_vga_enabled) { if (pci_enabled) { pci_cirrus_vga_init(pci_bus); } else { isa_cirrus_vga_init(); } } else if (vmsvga_enabled) { if (pci_enabled) pci_vmsvga_init(pci_bus); else fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __FUNCTION__); } else if (std_vga_enabled) { if (pci_enabled) { pci_vga_init(pci_bus, 0, 0); } else { isa_vga_init(); } } rtc_state = rtc_init(0x70, i8259[8], 2000); qemu_register_boot_set(pc_boot_set, rtc_state); register_ioport_read(0x92, 1, 1, ioport92_read, NULL); register_ioport_write(0x92, 1, 1, ioport92_write, NULL); if (pci_enabled) { ioapic = ioapic_init(); } pit = pit_init(0x40, i8259[0]); pcspk_init(pit); if (!no_hpet) { hpet_init(i8259); } if (pci_enabled) { pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic); } for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { serial_init(serial_io[i], i8259[serial_irq[i]], 115200, serial_hds[i]); } } for(i = 0; i < MAX_PARALLEL_PORTS; i++) { if (parallel_hds[i]) { parallel_init(parallel_io[i], i8259[parallel_irq[i]], parallel_hds[i]); } } watchdog_pc_init(pci_bus); for(i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) pc_init_ne2k_isa(nd, i8259); else pci_nic_init(pci_bus, nd, -1, "ne2k_pci"); } qemu_system_hot_add_init(); if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { fprintf(stderr, "qemu: too many IDE bus\n"); exit(1); } for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); if (index != -1) hd[i] = drives_table[index].bdrv; else hd[i] = NULL; } if (pci_enabled) { pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, i8259); } else { for(i = 0; i < MAX_IDE_BUS; i++) { isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]], hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); } } i8042_init(i8259[1], i8259[12], 0x60); DMA_init(0); #ifdef HAS_AUDIO audio_init(pci_enabled ? pci_bus : NULL, i8259); #endif for(i = 0; i < MAX_FD; i++) { index = drive_get_index(IF_FLOPPY, 0, i); if (index != -1) fd[i] = drives_table[index].bdrv; else fd[i] = NULL; } floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd); cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd); if (pci_enabled && usb_enabled) { usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); } if (pci_enabled && acpi_enabled) { uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ i2c_bus *smbus; /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]); for (i = 0; i < 8; i++) { DeviceState *eeprom; eeprom = qdev_create((BusState *)smbus, "smbus-eeprom"); qdev_set_prop_int(eeprom, "address", 0x50 + i); qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256)); qdev_init(eeprom); } } if (i440fx_state) { i440fx_init_memory_mappings(i440fx_state); } if (pci_enabled) { int max_bus; int bus; max_bus = drive_get_max_bus(IF_SCSI); for (bus = 0; bus <= max_bus; bus++) { pci_create_simple(pci_bus, -1, "lsi53c895a"); } } /* Add virtio block devices */ if (pci_enabled) { int index; int unit_id = 0; while ((index = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) { pci_create_simple(pci_bus, -1, "virtio-blk-pci"); unit_id++; } } /* Add virtio balloon device */ if (pci_enabled && !no_virtio_balloon) { pci_create_simple(pci_bus, -1, "virtio-balloon-pci"); } /* Add virtio console devices */ if (pci_enabled) { for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { if (virtcon_hds[i]) { pci_create_simple(pci_bus, -1, "virtio-console-pci"); } } } }


static ssize_t v9fs_synth_lgetxattr(FsContext *ctx, V9fsPath *path, const char *name, void *value, size_t size) { errno = ENOTSUP; return -1; }


static void aw_emac_cleanup(NetClientState *nc) { AwEmacState *s = qemu_get_nic_opaque(nc); s->nic = NULL; }


static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features) { VirtIONet *n = VIRTIO_NET(vdev); int i; virtio_net_set_multiqueue(n, !!(features & (1 << VIRTIO_NET_F_MQ)), !!(features & (1 << VIRTIO_NET_F_CTRL_VQ))); virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF))); if (n->has_vnet_hdr) { tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer, (features >> VIRTIO_NET_F_GUEST_CSUM) & 1, (features >> VIRTIO_NET_F_GUEST_TSO4) & 1, (features >> VIRTIO_NET_F_GUEST_TSO6) & 1, (features >> VIRTIO_NET_F_GUEST_ECN) & 1, (features >> VIRTIO_NET_F_GUEST_UFO) & 1); } for (i = 0; i < n->max_queues; i++) { NetClientState *nc = qemu_get_subqueue(n->nic, i); if (!nc->peer || nc->peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) { continue; } if (!tap_get_vhost_net(nc->peer)) { continue; } vhost_net_ack_features(tap_get_vhost_net(nc->peer), features); } }


void qemu_del_nic(NICState *nic) { int i, queues = nic->conf->queues; /* If this is a peer NIC and peer has already been deleted, free it now. */ if (nic->peer_deleted) { for (i = 0; i < queues; i++) { qemu_free_net_client(qemu_get_subqueue(nic, i)->peer); } } for (i = queues - 1; i >= 0; i--) { NetClientState *nc = qemu_get_subqueue(nic, i); qemu_cleanup_net_client(nc); qemu_free_net_client(nc); } }


static int vfio_initfn(PCIDevice *pdev) { VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); VFIODevice *vbasedev_iter; VFIOGroup *group; char path[PATH_MAX], iommu_group_path[PATH_MAX], *group_name; ssize_t len; struct stat st; int groupid; int ret; /* Check that the host device exists */ snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/", vdev->host.domain, vdev->host.bus, vdev->host.slot, vdev->host.function); if (stat(path, &st) < 0) { error_report("vfio: error: no such host device: %s", path); return -errno; } vdev->vbasedev.ops = &vfio_pci_ops; vdev->vbasedev.type = VFIO_DEVICE_TYPE_PCI; vdev->vbasedev.name = g_strdup_printf("%04x:%02x:%02x.%01x", vdev->host.domain, vdev->host.bus, vdev->host.slot, vdev->host.function); strncat(path, "iommu_group", sizeof(path) - strlen(path) - 1); len = readlink(path, iommu_group_path, sizeof(path)); if (len <= 0 || len >= sizeof(path)) { error_report("vfio: error no iommu_group for device"); return len < 0 ? -errno : -ENAMETOOLONG; } iommu_group_path[len] = 0; group_name = basename(iommu_group_path); if (sscanf(group_name, "%d", &groupid) != 1) { error_report("vfio: error reading %s: %m", path); return -errno; } trace_vfio_initfn(vdev->vbasedev.name, groupid); group = vfio_get_group(groupid, pci_device_iommu_address_space(pdev)); if (!group) { error_report("vfio: failed to get group %d", groupid); return -ENOENT; } snprintf(path, sizeof(path), "%04x:%02x:%02x.%01x", vdev->host.domain, vdev->host.bus, vdev->host.slot, vdev->host.function); QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { if (strcmp(vbasedev_iter->name, vdev->vbasedev.name) == 0) { error_report("vfio: error: device %s is already attached", path); vfio_put_group(group); return -EBUSY; } } ret = vfio_get_device(group, path, &vdev->vbasedev); if (ret) { error_report("vfio: failed to get device %s", path); vfio_put_group(group); return ret; } ret = vfio_populate_device(vdev); if (ret) { return ret; } /* Get a copy of config space */ ret = pread(vdev->vbasedev.fd, vdev->pdev.config, MIN(pci_config_size(&vdev->pdev), vdev->config_size), vdev->config_offset); if (ret < (int)MIN(pci_config_size(&vdev->pdev), vdev->config_size)) { ret = ret < 0 ? -errno : -EFAULT; error_report("vfio: Failed to read device config space"); return ret; } /* vfio emulates a lot for us, but some bits need extra love */ vdev->emulated_config_bits = g_malloc0(vdev->config_size); /* QEMU can choose to expose the ROM or not */ memset(vdev->emulated_config_bits + PCI_ROM_ADDRESS, 0xff, 4); /* * The PCI spec reserves vendor ID 0xffff as an invalid value. The * device ID is managed by the vendor and need only be a 16-bit value. * Allow any 16-bit value for subsystem so they can be hidden or changed. */ if (vdev->vendor_id != PCI_ANY_ID) { if (vdev->vendor_id >= 0xffff) { error_report("vfio: Invalid PCI vendor ID provided"); return -EINVAL; } vfio_add_emulated_word(vdev, PCI_VENDOR_ID, vdev->vendor_id, ~0); trace_vfio_pci_emulated_vendor_id(vdev->vbasedev.name, vdev->vendor_id); } else { vdev->vendor_id = pci_get_word(pdev->config + PCI_VENDOR_ID); } if (vdev->device_id != PCI_ANY_ID) { if (vdev->device_id > 0xffff) { error_report("vfio: Invalid PCI device ID provided"); return -EINVAL; } vfio_add_emulated_word(vdev, PCI_DEVICE_ID, vdev->device_id, ~0); trace_vfio_pci_emulated_device_id(vdev->vbasedev.name, vdev->device_id); } else { vdev->device_id = pci_get_word(pdev->config + PCI_DEVICE_ID); } if (vdev->sub_vendor_id != PCI_ANY_ID) { if (vdev->sub_vendor_id > 0xffff) { error_report("vfio: Invalid PCI subsystem vendor ID provided"); return -EINVAL; } vfio_add_emulated_word(vdev, PCI_SUBSYSTEM_VENDOR_ID, vdev->sub_vendor_id, ~0); trace_vfio_pci_emulated_sub_vendor_id(vdev->vbasedev.name, vdev->sub_vendor_id); } if (vdev->sub_device_id != PCI_ANY_ID) { if (vdev->sub_device_id > 0xffff) { error_report("vfio: Invalid PCI subsystem device ID provided"); return -EINVAL; } vfio_add_emulated_word(vdev, PCI_SUBSYSTEM_ID, vdev->sub_device_id, ~0); trace_vfio_pci_emulated_sub_device_id(vdev->vbasedev.name, vdev->sub_device_id); } /* QEMU can change multi-function devices to single function, or reverse */ vdev->emulated_config_bits[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_MULTI_FUNCTION; /* Restore or clear multifunction, this is always controlled by QEMU */ if (vdev->pdev.cap_present & QEMU_PCI_CAP_MULTIFUNCTION) { vdev->pdev.config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION; } else { vdev->pdev.config[PCI_HEADER_TYPE] &= ~PCI_HEADER_TYPE_MULTI_FUNCTION; } /* * Clear host resource mapping info. If we choose not to register a * BAR, such as might be the case with the option ROM, we can get * confusing, unwritable, residual addresses from the host here. */ memset(&vdev->pdev.config[PCI_BASE_ADDRESS_0], 0, 24); memset(&vdev->pdev.config[PCI_ROM_ADDRESS], 0, 4); vfio_pci_size_rom(vdev); ret = vfio_msix_early_setup(vdev); if (ret) { return ret; } vfio_map_bars(vdev); ret = vfio_add_capabilities(vdev); if (ret) { goto out_teardown; } /* QEMU emulates all of MSI & MSIX */ if (pdev->cap_present & QEMU_PCI_CAP_MSIX) { memset(vdev->emulated_config_bits + pdev->msix_cap, 0xff, MSIX_CAP_LENGTH); } if (pdev->cap_present & QEMU_PCI_CAP_MSI) { memset(vdev->emulated_config_bits + pdev->msi_cap, 0xff, vdev->msi_cap_size); } if (vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1)) { vdev->intx.mmap_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, vfio_intx_mmap_enable, vdev); pci_device_set_intx_routing_notifier(&vdev->pdev, vfio_intx_update); ret = vfio_intx_enable(vdev); if (ret) { goto out_teardown; } } vfio_register_err_notifier(vdev); vfio_register_req_notifier(vdev); vfio_setup_resetfn_quirk(vdev); return 0; out_teardown: pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); vfio_teardown_msi(vdev); vfio_unregister_bars(vdev); return ret; }


static void absolute_mouse_grab(void) { int mouse_x, mouse_y; if (SDL_GetAppState() & SDL_APPINPUTFOCUS) { SDL_GetMouseState(&mouse_x, &mouse_y); if (mouse_x > 0 && mouse_x < real_screen->w - 1 && mouse_y > 0 && mouse_y < real_screen->h - 1) { sdl_grab_start(); } } }


int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp) { int fd; switch (remote->type) { case SOCKET_ADDRESS_KIND_INET: fd = inet_dgram_saddr(remote->u.inet, local ? local->u.inet : NULL, errp); break; default: error_setg(errp, "socket type unsupported for datagram"); fd = -1; } return fd; }


static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_index) { if (s->correct_ts_overflow && st->pts_wrap_bits < 63 && st->pts_wrap_reference == AV_NOPTS_VALUE && st->first_dts != AV_NOPTS_VALUE) { int i; // reference time stamp should be 60 s before first time stamp int64_t pts_wrap_reference = st->first_dts - av_rescale(60, st->time_base.den, st->time_base.num); // if first time stamp is not more than 1/8 and 60s before the wrap point, subtract rather than add wrap offset int pts_wrap_behavior = (st->first_dts < (1LL<<st->pts_wrap_bits) - (1LL<<st->pts_wrap_bits-3)) || (st->first_dts < (1LL<<st->pts_wrap_bits) - av_rescale(60, st->time_base.den, st->time_base.num)) ? AV_PTS_WRAP_ADD_OFFSET : AV_PTS_WRAP_SUB_OFFSET; AVProgram *first_program = av_find_program_from_stream(s, NULL, stream_index); if (!first_program) { int default_stream_index = av_find_default_stream_index(s); if (s->streams[default_stream_index]->pts_wrap_reference == AV_NOPTS_VALUE) { for (i=0; i<s->nb_streams; i++) { s->streams[i]->pts_wrap_reference = pts_wrap_reference; s->streams[i]->pts_wrap_behavior = pts_wrap_behavior; } } else { st->pts_wrap_reference = s->streams[default_stream_index]->pts_wrap_reference; st->pts_wrap_behavior = s->streams[default_stream_index]->pts_wrap_behavior; } } else { AVProgram *program = first_program; while (program) { if (program->pts_wrap_reference != AV_NOPTS_VALUE) { pts_wrap_reference = program->pts_wrap_reference; pts_wrap_behavior = program->pts_wrap_behavior; break; } program = av_find_program_from_stream(s, program, stream_index); } // update every program with differing pts_wrap_reference program = first_program; while(program) { if (program->pts_wrap_reference != pts_wrap_reference) { for (i=0; i<program->nb_stream_indexes; i++) { s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; } program->pts_wrap_reference = pts_wrap_reference; program->pts_wrap_behavior = pts_wrap_behavior; } program = av_find_program_from_stream(s, program, stream_index); } } return 1; } return 0; }


uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem, uint64_t code) { uint64_t r; switch (num) { case 0x500: /* KVM hypercall */ r = s390_virtio_hypercall(env); break; case 0x44: /* yield */ r = 0; break; case 0x308: /* ipl */ r = 0; break; default: r = -1; break; } if (r) { program_interrupt(env, PGM_OPERATION, ILEN_LATER_INC); } return r; }


static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkExtent *extent, VmdkMetaData *m_data, uint64_t offset, int allocate) { unsigned int l1_index, l2_offset, l2_index; int min_index, i, j; uint32_t min_count, *l2_table, tmp = 0; uint64_t cluster_offset; if (m_data) m_data->valid = 0; l1_index = (offset >> 9) / extent->l1_entry_sectors; if (l1_index >= extent->l1_size) { return 0; } l2_offset = extent->l1_table[l1_index]; if (!l2_offset) { return 0; } for (i = 0; i < L2_CACHE_SIZE; i++) { if (l2_offset == extent->l2_cache_offsets[i]) { /* increment the hit count */ if (++extent->l2_cache_counts[i] == 0xffffffff) { for (j = 0; j < L2_CACHE_SIZE; j++) { extent->l2_cache_counts[j] >>= 1; } } l2_table = extent->l2_cache + (i * extent->l2_size); goto found; } } /* not found: load a new entry in the least used one */ min_index = 0; min_count = 0xffffffff; for (i = 0; i < L2_CACHE_SIZE; i++) { if (extent->l2_cache_counts[i] < min_count) { min_count = extent->l2_cache_counts[i]; min_index = i; } } l2_table = extent->l2_cache + (min_index * extent->l2_size); if (bdrv_pread( extent->file, (int64_t)l2_offset * 512, l2_table, extent->l2_size * sizeof(uint32_t) ) != extent->l2_size * sizeof(uint32_t)) { return 0; } extent->l2_cache_offsets[min_index] = l2_offset; extent->l2_cache_counts[min_index] = 1; found: l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size; cluster_offset = le32_to_cpu(l2_table[l2_index]); if (!cluster_offset) { if (!allocate) return 0; // Avoid the L2 tables update for the images that have snapshots. cluster_offset = bdrv_getlength(extent->file); bdrv_truncate( extent->file, cluster_offset + (extent->cluster_sectors << 9) ); cluster_offset >>= 9; tmp = cpu_to_le32(cluster_offset); l2_table[l2_index] = tmp; /* First of all we write grain itself, to avoid race condition * that may to corrupt the image. * This problem may occur because of insufficient space on host disk * or inappropriate VM shutdown. */ if (get_whole_cluster( bs, extent, cluster_offset, offset, allocate) == -1) return 0; if (m_data) { m_data->offset = tmp; m_data->l1_index = l1_index; m_data->l2_index = l2_index; m_data->l2_offset = l2_offset; m_data->valid = 1; } } cluster_offset <<= 9; return cluster_offset; }


void qemu_set_fd_handler(int fd, IOHandler *fd_read, IOHandler *fd_write, void *opaque) { iohandler_init(); aio_set_fd_handler(iohandler_ctx, fd, false, fd_read, fd_write, NULL, opaque); }


static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, uint64_t value, unsigned size, MemTxAttrs attrs) { NVICState *s = (NVICState *)opaque; uint32_t offset = addr; unsigned i, startvec, end; unsigned setval = 0; trace_nvic_sysreg_write(addr, value, size); if (attrs.user && !nvic_user_access_ok(s, addr)) { /* Generate BusFault for unprivileged accesses */ return MEMTX_ERROR; } switch (offset) { case 0x100 ... 0x13f: /* NVIC Set enable */ offset += 0x80; setval = 1; /* fall through */ case 0x180 ... 0x1bf: /* NVIC Clear enable */ startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ; for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { if (value & (1 << i)) { s->vectors[startvec + i].enabled = setval; } } nvic_irq_update(s); return MEMTX_OK; case 0x200 ... 0x23f: /* NVIC Set pend */ /* the special logic in armv7m_nvic_set_pending() * is not needed since IRQs are never escalated */ offset += 0x80; setval = 1; /* fall through */ case 0x280 ... 0x2bf: /* NVIC Clear pend */ startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */ for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { if (value & (1 << i)) { s->vectors[startvec + i].pending = setval; } } nvic_irq_update(s); return MEMTX_OK; case 0x300 ... 0x33f: /* NVIC Active */ return MEMTX_OK; /* R/O */ case 0x400 ... 0x5ef: /* NVIC Priority */ startvec = 8 * (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */ for (i = 0; i < size && startvec + i < s->num_irq; i++) { set_prio(s, startvec + i, (value >> (i * 8)) & 0xff); } nvic_irq_update(s); return MEMTX_OK; case 0xd18 ... 0xd23: /* System Handler Priority. */ for (i = 0; i < size; i++) { unsigned hdlidx = (offset - 0xd14) + i; set_prio(s, hdlidx, (value >> (i * 8)) & 0xff); } nvic_irq_update(s); return MEMTX_OK; } if (size == 4) { nvic_writel(s, offset, value); return MEMTX_OK; } qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad write of size %d at offset 0x%x\n", size, offset); /* This is UNPREDICTABLE; treat as RAZ/WI */ return MEMTX_OK; }


static void phys_page_set_level(PhysPageEntry *lp, hwaddr *index, hwaddr *nb, uint16_t leaf, int level) { PhysPageEntry *p; int i; hwaddr step = (hwaddr)1 << (level * P_L2_BITS); if (lp->skip && lp->ptr == PHYS_MAP_NODE_NIL) { lp->ptr = phys_map_node_alloc(); p = next_map.nodes[lp->ptr]; if (level == 0) { for (i = 0; i < P_L2_SIZE; i++) { p[i].skip = 0; p[i].ptr = PHYS_SECTION_UNASSIGNED; } } } else { p = next_map.nodes[lp->ptr]; } lp = &p[(*index >> (level * P_L2_BITS)) & (P_L2_SIZE - 1)]; while (*nb && lp < &p[P_L2_SIZE]) { if ((*index & (step - 1)) == 0 && *nb >= step) { lp->skip = 0; lp->ptr = leaf; *index += step; *nb -= step; } else { phys_page_set_level(lp, index, nb, leaf, level - 1); } ++lp; } }


static void map_page(uint8_t **ptr, uint64_t addr, uint32_t wanted) { target_phys_addr_t len = wanted; if (*ptr) { cpu_physical_memory_unmap(*ptr, len, 1, len); } *ptr = cpu_physical_memory_map(addr, &len, 1); if (len < wanted) { cpu_physical_memory_unmap(*ptr, len, 1, len); *ptr = NULL; } }


static VmdkExtent *vmdk_add_extent(BlockDriverState *bs, BlockDriverState *file, bool flat, int64_t sectors, int64_t l1_offset, int64_t l1_backup_offset, uint32_t l1_size, int l2_size, unsigned int cluster_sectors) { VmdkExtent *extent; BDRVVmdkState *s = bs->opaque; s->extents = g_realloc(s->extents, (s->num_extents + 1) * sizeof(VmdkExtent)); extent = &s->extents[s->num_extents]; s->num_extents++; memset(extent, 0, sizeof(VmdkExtent)); extent->file = file; extent->flat = flat; extent->sectors = sectors; extent->l1_table_offset = l1_offset; extent->l1_backup_table_offset = l1_backup_offset; extent->l1_size = l1_size; extent->l1_entry_sectors = l2_size * cluster_sectors; extent->l2_size = l2_size; extent->cluster_sectors = cluster_sectors; if (s->num_extents > 1) { extent->end_sector = (*(extent - 1)).end_sector + extent->sectors; } else { extent->end_sector = extent->sectors; } bs->total_sectors = extent->end_sector; return extent; }


static void ppc_heathrow_init (int ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { CPUState *env = NULL, *envs[MAX_CPUS]; char buf[1024]; qemu_irq *pic, **heathrow_irqs; nvram_t nvram; m48t59_t *m48t59; int linux_boot, i; unsigned long bios_offset, vga_bios_offset; uint32_t kernel_base, kernel_size, initrd_base, initrd_size; PCIBus *pci_bus; MacIONVRAMState *nvr; int vga_bios_size, bios_size; qemu_irq *dummy_irq; int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index; int ppc_boot_device = boot_device[0]; linux_boot = (kernel_filename != NULL); /* init CPUs */ if (cpu_model == NULL) cpu_model = "default"; for (i = 0; i < smp_cpus; i++) { env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); } /* Set time-base frequency to 100 Mhz */ cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); env->osi_call = vga_osi_call; qemu_register_reset(&cpu_ppc_reset, env); register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); envs[i] = env; } if (env->nip < 0xFFF80000) { /* Special test for PowerPC 601: * the boot vector is at 0xFFF00100, then we need a 1MB BIOS. * But the NVRAM is located at 0xFFF04000... */ cpu_abort(env, "G3BW Mac hardware can not handle 1 MB BIOS\n"); } /* allocate RAM */ cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); /* allocate and load BIOS */ bios_offset = ram_size + vga_ram_size; if (bios_name == NULL) bios_name = BIOS_FILENAME; snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); bios_size = load_image(buf, phys_ram_base + bios_offset); if (bios_size < 0 || bios_size > BIOS_SIZE) { cpu_abort(env, "qemu: could not load PowerPC bios '%s'\n", buf); exit(1); } bios_size = (bios_size + 0xfff) & ~0xfff; if (bios_size > 0x00080000) { /* As the NVRAM is located at 0xFFF04000, we cannot use 1 MB BIOSes */ cpu_abort(env, "G3BW Mac hardware can not handle 1 MB BIOS\n"); } cpu_register_physical_memory((uint32_t)(-bios_size), bios_size, bios_offset | IO_MEM_ROM); /* allocate and load VGA BIOS */ vga_bios_offset = bios_offset + bios_size; snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME); vga_bios_size = load_image(buf, phys_ram_base + vga_bios_offset + 8); if (vga_bios_size < 0) { /* if no bios is present, we can still work */ fprintf(stderr, "qemu: warning: could not load VGA bios '%s'\n", buf); vga_bios_size = 0; } else { /* set a specific header (XXX: find real Apple format for NDRV drivers) */ phys_ram_base[vga_bios_offset] = 'N'; phys_ram_base[vga_bios_offset + 1] = 'D'; phys_ram_base[vga_bios_offset + 2] = 'R'; phys_ram_base[vga_bios_offset + 3] = 'V'; cpu_to_be32w((uint32_t *)(phys_ram_base + vga_bios_offset + 4), vga_bios_size); vga_bios_size += 8; } vga_bios_size = (vga_bios_size + 0xfff) & ~0xfff; if (linux_boot) { kernel_base = KERNEL_LOAD_ADDR; /* now we can load the kernel */ kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base); if (kernel_size < 0) { cpu_abort(env, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } /* load initrd */ if (initrd_filename) { initrd_base = INITRD_LOAD_ADDR; initrd_size = load_image(initrd_filename, phys_ram_base + initrd_base); if (initrd_size < 0) { cpu_abort(env, "qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } } else { initrd_base = 0; initrd_size = 0; } ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; initrd_base = 0; initrd_size = 0; } isa_mem_base = 0x80000000; /* Register 2 MB of ISA IO space */ isa_mmio_init(0xfe000000, 0x00200000); /* XXX: we register only 1 output pin for heathrow PIC */ heathrow_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *)); heathrow_irqs[0] = qemu_mallocz(smp_cpus * sizeof(qemu_irq) * 1); /* Connect the heathrow PIC outputs to the 6xx bus */ for (i = 0; i < smp_cpus; i++) { switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: heathrow_irqs[i] = heathrow_irqs[0] + (i * 1); heathrow_irqs[i][0] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; break; default: cpu_abort(env, "Bus model not supported on OldWorld Mac machine\n"); exit(1); } } /* init basic PC hardware */ if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { cpu_abort(env, "Only 6xx bus is supported on heathrow machine\n"); exit(1); } pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs); pci_bus = pci_grackle_init(0xfec00000, pic); pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size, vga_ram_size, vga_bios_offset, vga_bios_size); /* XXX: suppress that */ dummy_irq = i8259_init(NULL); /* XXX: use Mac Serial port */ serial_init(0x3f8, dummy_irq[4], serial_hds[0]); for(i = 0; i < nb_nics; i++) { if (!nd_table[i].model) nd_table[i].model = "ne2k_pci"; pci_nic_init(pci_bus, &nd_table[i], -1); } pci_cmd646_ide_init(pci_bus, &bs_table[0], 0); /* cuda also initialize ADB */ cuda_init(&cuda_mem_index, pic[0x12]); adb_kbd_init(&adb_bus); adb_mouse_init(&adb_bus); nvr = macio_nvram_init(&nvram_mem_index, 0x2000); pmac_format_nvram_partition(nvr, 0x2000); dbdma_init(&dbdma_mem_index); macio_init(pci_bus, 0x0017, 1, pic_mem_index, dbdma_mem_index, cuda_mem_index, nvr, 0, NULL); if (usb_enabled) { usb_ohci_init_pci(pci_bus, 3, -1); } if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) graphic_depth = 15; m48t59 = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59); nvram.opaque = m48t59; nvram.read_fn = &m48t59_read; nvram.write_fn = &m48t59_write; PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "HEATHROW", ram_size, ppc_boot_device, kernel_base, kernel_size, kernel_cmdline, initrd_base, initrd_size, /* XXX: need an option to load a NVRAM image */ 0, graphic_width, graphic_height, graphic_depth); /* No PCI init: the BIOS will do it */ /* Special port to get debug messages from Open-Firmware */ register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL); }


static void musicpal_gpio_write(void *opaque, target_phys_addr_t offset, uint64_t value, unsigned size) { musicpal_gpio_state *s = opaque; switch (offset) { case MP_GPIO_OE_HI: /* used for LCD brightness control */ s->lcd_brightness = (s->lcd_brightness & MP_GPIO_LCD_BRIGHTNESS) | (value & MP_OE_LCD_BRIGHTNESS); musicpal_gpio_brightness_update(s); break; case MP_GPIO_OUT_LO: s->out_state = (s->out_state & 0xFFFF0000) | (value & 0xFFFF); break; case MP_GPIO_OUT_HI: s->out_state = (s->out_state & 0xFFFF) | (value << 16); s->lcd_brightness = (s->lcd_brightness & 0xFFFF) | (s->out_state & MP_GPIO_LCD_BRIGHTNESS); musicpal_gpio_brightness_update(s); qemu_set_irq(s->out[3], (s->out_state >> MP_GPIO_I2C_DATA_BIT) & 1); qemu_set_irq(s->out[4], (s->out_state >> MP_GPIO_I2C_CLOCK_BIT) & 1); break; case MP_GPIO_IER_LO: s->ier = (s->ier & 0xFFFF0000) | (value & 0xFFFF); break; case MP_GPIO_IER_HI: s->ier = (s->ier & 0xFFFF) | (value << 16); break; case MP_GPIO_IMR_LO: s->imr = (s->imr & 0xFFFF0000) | (value & 0xFFFF); break; case MP_GPIO_IMR_HI: s->imr = (s->imr & 0xFFFF) | (value << 16); break; } }


static inline void scale_mv(AVSContext *h, int *d_x, int *d_y, cavs_vector *src, int distp) { int den = h->scale_den[src->ref]; *d_x = (src->x * distp * den + 256 + (src->x >> 31)) >> 9; *d_y = (src->y * distp * den + 256 + (src->y >> 31)) >> 9; }


static int usb_wacom_handle_data(USBDevice *dev, USBPacket *p) { USBWacomState *s = (USBWacomState *) dev; uint8_t buf[p->iov.size]; int ret = 0; switch (p->pid) { case USB_TOKEN_IN: if (p->devep == 1) { if (!(s->changed || s->idle)) return USB_RET_NAK; s->changed = 0; if (s->mode == WACOM_MODE_HID) ret = usb_mouse_poll(s, buf, p->iov.size); else if (s->mode == WACOM_MODE_WACOM) ret = usb_wacom_poll(s, buf, p->iov.size); usb_packet_copy(p, buf, ret); break; } /* Fall through. */ case USB_TOKEN_OUT: default: ret = USB_RET_STALL; break; } return ret; }


RGB_FUNCTIONS(rgb565) #undef RGB_IN #undef RGB_OUT #undef BPP /* bgr24 handling */ #define RGB_IN(r, g, b, s)\ {\ b = (s)[0];\ g = (s)[1];\ r = (s)[2];\ } #define RGB_OUT(d, r, g, b)\ {\ (d)[0] = b;\ (d)[1] = g;\ (d)[2] = r;\ } #define BPP 3 RGB_FUNCTIONS(bgr24) #undef RGB_IN #undef RGB_OUT #undef BPP /* rgb24 handling */ #define RGB_IN(r, g, b, s)\ {\ r = (s)[0];\ g = (s)[1];\ b = (s)[2];\ } #define RGB_OUT(d, r, g, b)\ {\ (d)[0] = r;\ (d)[1] = g;\ (d)[2] = b;\ } #define BPP 3 RGB_FUNCTIONS(rgb24) static void yuv444p_to_rgb24(AVPicture *dst, AVPicture *src, int width, int height) { uint8_t *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1; int w, y, cb, cr, r_add, g_add, b_add; uint8_t *cm = cropTbl + MAX_NEG_CROP; unsigned int r, g, b; d = dst->data[0]; y1_ptr = src->data[0]; cb_ptr = src->data[1]; cr_ptr = src->data[2]; for(;height > 0; height --) { d1 = d; for(w = width; w > 0; w--) { YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]); YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]); RGB_OUT(d1, r, g, b); d1 += BPP; y1_ptr++; cb_ptr++; cr_ptr++; } d += dst->linesize[0]; y1_ptr += src->linesize[0] - width; cb_ptr += src->linesize[1] - width; cr_ptr += src->linesize[2] - width; } }


int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f) { AudioFrame *new_frame; AudioFrame *queue_end = afq->frame_queue; /* find the end of the queue */ while (queue_end && queue_end->next) queue_end = queue_end->next; /* allocate new frame queue entry */ if (!(new_frame = av_malloc(sizeof(*new_frame)))) return AVERROR(ENOMEM); /* get frame parameters */ new_frame->next = NULL; new_frame->duration = f->nb_samples; if (f->pts != AV_NOPTS_VALUE) { new_frame->pts = av_rescale_q(f->pts, afq->avctx->time_base, (AVRational){ 1, afq->avctx->sample_rate }); afq->next_pts = new_frame->pts + new_frame->duration; } else { new_frame->pts = AV_NOPTS_VALUE; afq->next_pts = AV_NOPTS_VALUE; } /* add new frame to the end of the queue */ if (!queue_end) afq->frame_queue = new_frame; else queue_end->next = new_frame; /* add frame sample count */ afq->remaining_samples += f->nb_samples; #ifdef DEBUG ff_af_queue_log_state(afq); #endif return 0; }


yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0, const int16_t *ubuf[2], const int16_t *vbuf[2], const int16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, int y, enum AVPixelFormat target) { const uint8_t * const d128 = dither_8x8_220[y & 7]; int i; if (c->flags & SWS_ERROR_DIFFUSION) { int err = 0; int acc = 0; for (i = 0; i < dstW; i +=2) { int Y; Y = ((buf0[i + 0] + 64) >> 7); Y += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4; c->dither_error[0][i] = err; acc = 2*acc + (Y >= 128); Y -= 220*(acc&1); err = ((buf0[i + 1] + 64) >> 7); err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4; c->dither_error[0][i+1] = Y; acc = 2*acc + (err >= 128); err -= 220*(acc&1); if ((i & 7) == 6) output_pixel(*dest++, acc); } c->dither_error[0][i] = err; } else { for (i = 0; i < dstW; i += 8) { int acc = 0; accumulate_bit(acc, ((buf0[i + 0] + 64) >> 7) + d128[0]); accumulate_bit(acc, ((buf0[i + 1] + 64) >> 7) + d128[1]); accumulate_bit(acc, ((buf0[i + 2] + 64) >> 7) + d128[2]); accumulate_bit(acc, ((buf0[i + 3] + 64) >> 7) + d128[3]); accumulate_bit(acc, ((buf0[i + 4] + 64) >> 7) + d128[4]); accumulate_bit(acc, ((buf0[i + 5] + 64) >> 7) + d128[5]); accumulate_bit(acc, ((buf0[i + 6] + 64) >> 7) + d128[6]); accumulate_bit(acc, ((buf0[i + 7] + 64) >> 7) + d128[7]); output_pixel(*dest++, acc); } } }


static sPAPREventLogEntry *rtas_event_log_dequeue(uint32_t event_mask, bool exception) { sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); sPAPREventLogEntry *entry = NULL; /* we only queue EPOW events atm. */ if ((event_mask & EVENT_MASK_EPOW) == 0) { return NULL; } QTAILQ_FOREACH(entry, &spapr->pending_events, next) { if (entry->exception != exception) { continue; } /* EPOW and hotplug events are surfaced in the same manner */ if (entry->log_type == RTAS_LOG_TYPE_EPOW || entry->log_type == RTAS_LOG_TYPE_HOTPLUG) { break; } } if (entry) { QTAILQ_REMOVE(&spapr->pending_events, entry, next); } return entry; }


static int spapr_check_htab_fd(sPAPRMachineState *spapr) { int rc = 0; if (spapr->htab_fd_stale) { close(spapr->htab_fd); spapr->htab_fd = kvmppc_get_htab_fd(false); if (spapr->htab_fd < 0) { error_report("Unable to open fd for reading hash table from KVM: " "%s", strerror(errno)); rc = -1; } spapr->htab_fd_stale = false; } return rc; }


static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) { BDRVRawState *s = bs->opaque; void *buf = NULL; BlockDriver *drv; QEMUIOVector local_qiov; int ret; if (s->has_size && (offset > s->size || bytes > (s->size - offset))) { /* There's not enough space for the data. Don't write anything and just * fail to prevent leaking out of the size specified in options. */ return -ENOSPC; } if (offset > UINT64_MAX - s->offset) { ret = -EINVAL; goto fail; } if (bs->probed && offset < BLOCK_PROBE_BUF_SIZE && bytes) { /* Handling partial writes would be a pain - so we just * require that guests have 512-byte request alignment if * probing occurred */ QEMU_BUILD_BUG_ON(BLOCK_PROBE_BUF_SIZE != 512); QEMU_BUILD_BUG_ON(BDRV_SECTOR_SIZE != 512); assert(offset == 0 && bytes >= BLOCK_PROBE_BUF_SIZE); buf = qemu_try_blockalign(bs->file->bs, 512); if (!buf) { ret = -ENOMEM; goto fail; } ret = qemu_iovec_to_buf(qiov, 0, buf, 512); if (ret != 512) { ret = -EINVAL; goto fail; } drv = bdrv_probe_all(buf, 512, NULL); if (drv != bs->drv) { ret = -EPERM; goto fail; } /* Use the checked buffer, a malicious guest might be overwriting its * original buffer in the background. */ qemu_iovec_init(&local_qiov, qiov->niov + 1); qemu_iovec_add(&local_qiov, buf, 512); qemu_iovec_concat(&local_qiov, qiov, 512, qiov->size - 512); qiov = &local_qiov; } offset += s->offset; BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); fail: if (qiov == &local_qiov) { qemu_iovec_destroy(&local_qiov); } qemu_vfree(buf); return ret; }


void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size) { if (xen_enabled()) { return xen_map_cache(addr, *size, 1); } else { RAMBlock *block; QLIST_FOREACH(block, &ram_list.blocks, next) { if (addr - block->offset < block->length) { if (addr - block->offset + *size > block->length) *size = block->length - addr + block->offset; return block->host + (addr - block->offset); } } fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr); abort(); *size = 0; return NULL; } }


static void *qemu_dummy_cpu_thread_fn(void *arg) { #ifdef _WIN32 fprintf(stderr, "qtest is not supported under Windows\n"); exit(1); #else CPUState *cpu = arg; sigset_t waitset; int r; qemu_mutex_lock_iothread(); qemu_thread_get_self(cpu->thread); cpu->thread_id = qemu_get_thread_id(); cpu->exception_index = -1; cpu->can_do_io = 1; sigemptyset(&waitset); sigaddset(&waitset, SIG_IPI); /* signal CPU creation */ cpu->created = true; qemu_cond_signal(&qemu_cpu_cond); current_cpu = cpu; while (1) { current_cpu = NULL; qemu_mutex_unlock_iothread(); do { int sig; r = sigwait(&waitset, &sig); } while (r == -1 && (errno == EAGAIN || errno == EINTR)); if (r == -1) { perror("sigwait"); exit(1); } qemu_mutex_lock_iothread(); current_cpu = cpu; qemu_wait_io_event_common(cpu); } return NULL; #endif }


static void acpi_get_hotplug_info(AcpiMiscInfo *misc) { int i; PCIBus *bus = find_i440fx(); if (!bus) { /* Only PIIX supports ACPI hotplug */ memset(misc->slot_hotplug_enable, 0, sizeof misc->slot_hotplug_enable); return; } memset(misc->slot_hotplug_enable, 0xff, DIV_ROUND_UP(PCI_SLOT_MAX, BITS_PER_BYTE)); for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { PCIDeviceClass *pc; PCIDevice *pdev = bus->devices[i]; if (!pdev) { continue; } pc = PCI_DEVICE_GET_CLASS(pdev); if (pc->no_hotplug) { int slot = PCI_SLOT(i); clear_bit(slot, misc->slot_hotplug_enable); } } }


static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr) { int ret = 0, offset, cpus_offset; CPUState *cs; char cpu_model[32]; int smt = kvmppc_smt_threads(); uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)}; CPU_FOREACH(cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); DeviceClass *dc = DEVICE_GET_CLASS(cs); int index = spapr_vcpu_id(cpu); int compat_smt = MIN(smp_threads, ppc_compat_max_threads(cpu)); if ((index % smt) != 0) { continue; } snprintf(cpu_model, 32, "%s@%x", dc->fw_name, index); cpus_offset = fdt_path_offset(fdt, "/cpus"); if (cpus_offset < 0) { cpus_offset = fdt_add_subnode(fdt, 0, "cpus"); if (cpus_offset < 0) { return cpus_offset; } } offset = fdt_subnode_offset(fdt, cpus_offset, cpu_model); if (offset < 0) { offset = fdt_add_subnode(fdt, cpus_offset, cpu_model); if (offset < 0) { return offset; } } ret = fdt_setprop(fdt, offset, "ibm,pft-size", pft_size_prop, sizeof(pft_size_prop)); if (ret < 0) { return ret; } if (nb_numa_nodes > 1) { ret = spapr_fixup_cpu_numa_dt(fdt, offset, cpu); if (ret < 0) { return ret; } } ret = spapr_fixup_cpu_smt_dt(fdt, offset, cpu, compat_smt); if (ret < 0) { return ret; } spapr_populate_pa_features(cpu, fdt, offset, spapr->cas_legacy_guest_workaround); } return ret; }


void subch_device_save(SubchDev *s, QEMUFile *f) { int i; qemu_put_byte(f, s->cssid); qemu_put_byte(f, s->ssid); qemu_put_be16(f, s->schid); qemu_put_be16(f, s->devno); qemu_put_byte(f, s->thinint_active); /* SCHIB */ /* PMCW */ qemu_put_be32(f, s->curr_status.pmcw.intparm); qemu_put_be16(f, s->curr_status.pmcw.flags); qemu_put_be16(f, s->curr_status.pmcw.devno); qemu_put_byte(f, s->curr_status.pmcw.lpm); qemu_put_byte(f, s->curr_status.pmcw.pnom); qemu_put_byte(f, s->curr_status.pmcw.lpum); qemu_put_byte(f, s->curr_status.pmcw.pim); qemu_put_be16(f, s->curr_status.pmcw.mbi); qemu_put_byte(f, s->curr_status.pmcw.pom); qemu_put_byte(f, s->curr_status.pmcw.pam); qemu_put_buffer(f, s->curr_status.pmcw.chpid, 8); qemu_put_be32(f, s->curr_status.pmcw.chars); /* SCSW */ qemu_put_be16(f, s->curr_status.scsw.flags); qemu_put_be16(f, s->curr_status.scsw.ctrl); qemu_put_be32(f, s->curr_status.scsw.cpa); qemu_put_byte(f, s->curr_status.scsw.dstat); qemu_put_byte(f, s->curr_status.scsw.cstat); qemu_put_be16(f, s->curr_status.scsw.count); qemu_put_be64(f, s->curr_status.mba); qemu_put_buffer(f, s->curr_status.mda, 4); /* end SCHIB */ qemu_put_buffer(f, s->sense_data, 32); qemu_put_be64(f, s->channel_prog); /* last cmd */ qemu_put_byte(f, s->last_cmd.cmd_code); qemu_put_byte(f, s->last_cmd.flags); qemu_put_be16(f, s->last_cmd.count); qemu_put_be32(f, s->last_cmd.cda); qemu_put_byte(f, s->last_cmd_valid); qemu_put_byte(f, s->id.reserved); qemu_put_be16(f, s->id.cu_type); qemu_put_byte(f, s->id.cu_model); qemu_put_be16(f, s->id.dev_type); qemu_put_byte(f, s->id.dev_model); qemu_put_byte(f, s->id.unused); for (i = 0; i < ARRAY_SIZE(s->id.ciw); i++) { qemu_put_byte(f, s->id.ciw[i].type); qemu_put_byte(f, s->id.ciw[i].command); qemu_put_be16(f, s->id.ciw[i].count); } qemu_put_byte(f, s->ccw_fmt_1); qemu_put_byte(f, s->ccw_no_data_cnt); }


static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, EventNotifierHandler *handler, int n) { BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s))); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); VirtIOSCSIVring *r; int rc; /* Set up virtqueue notify */ rc = k->set_host_notifier(qbus->parent, n, true); if (rc != 0) { fprintf(stderr, "virtio-scsi: Failed to set host notifier (%d)\n", rc); s->dataplane_fenced = true; return NULL; } r = g_new(VirtIOSCSIVring, 1); r->host_notifier = *virtio_queue_get_host_notifier(vq); r->guest_notifier = *virtio_queue_get_guest_notifier(vq); aio_set_event_notifier(s->ctx, &r->host_notifier, false, handler); r->parent = s; if (!vring_setup(&r->vring, VIRTIO_DEVICE(s), n)) { fprintf(stderr, "virtio-scsi: VRing setup failed\n"); goto fail_vring; } return r; fail_vring: aio_set_event_notifier(s->ctx, &r->host_notifier, false, NULL); k->set_host_notifier(qbus->parent, n, false); g_free(r); return NULL; }


static void do_change_block(const char *device, const char *filename, const char *fmt) { BlockDriverState *bs; BlockDriver *drv = NULL; bs = bdrv_find(device); if (!bs) { term_printf("device not found\n"); return; } if (fmt) { drv = bdrv_find_format(fmt); if (!drv) { term_printf("invalid format %s\n", fmt); return; } } if (eject_device(bs, 0) < 0) return; bdrv_open2(bs, filename, 0, drv); qemu_key_check(bs, filename); }


static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features, uint32_t *ext_features, uint32_t *ext2_features, uint32_t *ext3_features, uint32_t *kvm_features, uint32_t *svm_features) { if (!lookup_feature(features, flagname, NULL, feature_name) && !lookup_feature(ext_features, flagname, NULL, ext_feature_name) && !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) && !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) && !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name) && !lookup_feature(svm_features, flagname, NULL, svm_feature_name)) fprintf(stderr, "CPU feature %s not found\n", flagname); }


static void test_machine(const void *data) { const testdef_t *test = data; char tmpname[] = "/tmp/qtest-boot-serial-XXXXXX"; int fd; fd = mkstemp(tmpname); g_assert(fd != -1); /* * Make sure that this test uses tcg if available: It is used as a * fast-enough smoketest for that. */ global_qtest = qtest_startf("-M %s,accel=tcg:kvm " "-chardev file,id=serial0,path=%s " "-no-shutdown -serial chardev:serial0 %s", test->machine, tmpname, test->extra); unlink(tmpname); check_guest_output(test, fd); qtest_quit(global_qtest); close(fd); }


START_TEST(qstring_from_substr_test) { QString *qs; qs = qstring_from_substr("virtualization", 3, 9); fail_unless(qs != NULL); fail_unless(strcmp(qstring_get_str(qs), "tualiza") == 0); QDECREF(qs); }


void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) { qdev_prop_set(dev, name, &value, PROP_TYPE_PTR); }


static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size) { /* This always zero-extends and writes to a full 128 bit wide vector */ TCGv_i64 tmplo = tcg_temp_new_i64(); TCGv_i64 tmphi; if (size < 4) { TCGMemOp memop = MO_TE + size; tmphi = tcg_const_i64(0); tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop); } else { TCGv_i64 tcg_hiaddr; tmphi = tcg_temp_new_i64(); tcg_hiaddr = tcg_temp_new_i64(); tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), MO_TEQ); tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8); tcg_gen_qemu_ld_i64(tmphi, tcg_hiaddr, get_mem_index(s), MO_TEQ); tcg_temp_free_i64(tcg_hiaddr); } tcg_gen_st_i64(tmplo, cpu_env, fp_reg_offset(destidx, MO_64)); tcg_gen_st_i64(tmphi, cpu_env, fp_reg_hi_offset(destidx)); tcg_temp_free_i64(tmplo); tcg_temp_free_i64(tmphi); }


static inline void gen_op_eval_fbne(TCGv dst, TCGv src, unsigned int fcc_offset) { gen_mov_reg_FCC0(dst, src, fcc_offset); gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset); tcg_gen_or_tl(dst, dst, cpu_tmp0); }


av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, unsigned int *sample_rate, int channels, enum CodecID *codec_id) { AlsaData *s = ctx->priv_data; const char *audio_device; int res, flags = 0; snd_pcm_format_t format; snd_pcm_t *h; snd_pcm_hw_params_t *hw_params; snd_pcm_uframes_t buffer_size, period_size; int64_t layout = ctx->streams[0]->codec->channel_layout; if (ctx->filename[0] == 0) audio_device = "default"; else audio_device = ctx->filename; if (*codec_id == CODEC_ID_NONE) *codec_id = DEFAULT_CODEC_ID; format = codec_id_to_pcm_format(*codec_id); if (format == SND_PCM_FORMAT_UNKNOWN) { av_log(ctx, AV_LOG_ERROR, "sample format 0x%04x is not supported\n", *codec_id); return AVERROR(ENOSYS); } s->frame_size = av_get_bits_per_sample(*codec_id) / 8 * channels; if (ctx->flags & AVFMT_FLAG_NONBLOCK) { flags = SND_PCM_NONBLOCK; } res = snd_pcm_open(&h, audio_device, mode, flags); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot open audio device %s (%s)\n", audio_device, snd_strerror(res)); return AVERROR(EIO); } res = snd_pcm_hw_params_malloc(&hw_params); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot allocate hardware parameter structure (%s)\n", snd_strerror(res)); goto fail1; } res = snd_pcm_hw_params_any(h, hw_params); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot initialize hardware parameter structure (%s)\n", snd_strerror(res)); goto fail; } res = snd_pcm_hw_params_set_access(h, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set access type (%s)\n", snd_strerror(res)); goto fail; } res = snd_pcm_hw_params_set_format(h, hw_params, format); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set sample format 0x%04x %d (%s)\n", *codec_id, format, snd_strerror(res)); goto fail; } res = snd_pcm_hw_params_set_rate_near(h, hw_params, sample_rate, 0); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set sample rate (%s)\n", snd_strerror(res)); goto fail; } res = snd_pcm_hw_params_set_channels(h, hw_params, channels); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set channel count to %d (%s)\n", channels, snd_strerror(res)); goto fail; } snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size); buffer_size = FFMIN(buffer_size, ALSA_BUFFER_SIZE_MAX); /* TODO: maybe use ctx->max_picture_buffer somehow */ res = snd_pcm_hw_params_set_buffer_size_near(h, hw_params, &buffer_size); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set ALSA buffer size (%s)\n", snd_strerror(res)); goto fail; } snd_pcm_hw_params_get_period_size_min(hw_params, &period_size, NULL); if (!period_size) period_size = buffer_size / 4; res = snd_pcm_hw_params_set_period_size_near(h, hw_params, &period_size, NULL); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set ALSA period size (%s)\n", snd_strerror(res)); goto fail; } s->period_size = period_size; res = snd_pcm_hw_params(h, hw_params); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set parameters (%s)\n", snd_strerror(res)); goto fail; } snd_pcm_hw_params_free(hw_params); if (channels > 2 && layout) { if (find_reorder_func(s, *codec_id, layout, mode == SND_PCM_STREAM_PLAYBACK) < 0) { char name[128]; av_get_channel_layout_string(name, sizeof(name), channels, layout); av_log(ctx, AV_LOG_WARNING, "ALSA channel layout unknown or unimplemented for %s %s.\n", name, mode == SND_PCM_STREAM_PLAYBACK ? "playback" : "capture"); } if (s->reorder_func) { s->reorder_buf_size = buffer_size; s->reorder_buf = av_malloc(s->reorder_buf_size * s->frame_size); if (!s->reorder_buf) goto fail1; } } s->h = h; return 0; fail: snd_pcm_hw_params_free(hw_params); fail1: snd_pcm_close(h); return AVERROR(EIO); }


bool kvm_arch_stop_on_emulation_error(CPUState *env) { return !(env->cr[0] & CR0_PE_MASK) || ((env->segs[R_CS].selector & 3) != 3); }


static ssize_t block_crypto_write_func(QCryptoBlock *block, size_t offset, const uint8_t *buf, size_t buflen, Error **errp, void *opaque) { struct BlockCryptoCreateData *data = opaque; ssize_t ret; ret = blk_pwrite(data->blk, offset, buf, buflen, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not write encryption header"); return ret; } return ret; }


static int bdrv_check_perm(BlockDriverState *bs, uint64_t cumulative_perms, uint64_t cumulative_shared_perms, Error **errp) { BlockDriver *drv = bs->drv; BdrvChild *c; int ret; /* Write permissions never work with read-only images */ if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) && bdrv_is_read_only(bs)) { error_setg(errp, "Block node is read-only"); return -EPERM; } /* Check this node */ if (!drv) { return 0; } if (drv->bdrv_check_perm) { return drv->bdrv_check_perm(bs, cumulative_perms, cumulative_shared_perms, errp); } /* Drivers that never have children can omit .bdrv_child_perm() */ if (!drv->bdrv_child_perm) { assert(QLIST_EMPTY(&bs->children)); return 0; } /* Check all children */ QLIST_FOREACH(c, &bs->children, next) { uint64_t cur_perm, cur_shared; drv->bdrv_child_perm(bs, c, c->role, cumulative_perms, cumulative_shared_perms, &cur_perm, &cur_shared); ret = bdrv_child_check_perm(c, cur_perm, cur_shared, errp); if (ret < 0) { return ret; } } return 0; }


static void test_qemu_strtosz_simple(void) { const char *str; char *endptr = NULL; int64_t res; str = "0"; res = qemu_strtosz(str, &endptr); g_assert_cmpint(res, ==, 0); g_assert(endptr == str + 1); str = "12345"; res = qemu_strtosz(str, &endptr); g_assert_cmpint(res, ==, 12345); g_assert(endptr == str + 5); res = qemu_strtosz(str, NULL); g_assert_cmpint(res, ==, 12345); /* Note: precision is 53 bits since we're parsing with strtod() */ str = "9007199254740991"; /* 2^53-1 */ res = qemu_strtosz(str, &endptr); g_assert_cmpint(res, ==, 0x1fffffffffffff); g_assert(endptr == str + 16); str = "9007199254740992"; /* 2^53 */ res = qemu_strtosz(str, &endptr); g_assert_cmpint(res, ==, 0x20000000000000); g_assert(endptr == str + 16); str = "9007199254740993"; /* 2^53+1 */ res = qemu_strtosz(str, &endptr); g_assert_cmpint(res, ==, 0x20000000000000); /* rounded to 53 bits */ g_assert(endptr == str + 16); str = "9223372036854774784"; /* 0x7ffffffffffffc00 (53 msbs set) */ res = qemu_strtosz(str, &endptr); g_assert_cmpint(res, ==, 0x7ffffffffffffc00); g_assert(endptr == str + 19); str = "9223372036854775295"; /* 0x7ffffffffffffdff */ res = qemu_strtosz(str, &endptr); g_assert_cmpint(res, ==, 0x7ffffffffffffc00); /* rounded to 53 bits */ g_assert(endptr == str + 19); /* 0x7ffffffffffffe00..0x7fffffffffffffff get rounded to * 0x8000000000000000, thus -ERANGE; see test_qemu_strtosz_erange() */ }


void vring_teardown(Vring *vring) { hostmem_finalize(&vring->hostmem); }


static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd, NvmeRequest *req) { NvmeRwCmd *rw = (NvmeRwCmd *)cmd; uint32_t nlb = le32_to_cpu(rw->nlb) + 1; uint64_t slba = le64_to_cpu(rw->slba); uint64_t prp1 = le64_to_cpu(rw->prp1); uint64_t prp2 = le64_to_cpu(rw->prp2); uint8_t lba_index = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas); uint8_t data_shift = ns->id_ns.lbaf[lba_index].ds; uint64_t data_size = nlb << data_shift; uint64_t aio_slba = slba << (data_shift - BDRV_SECTOR_BITS); int is_write = rw->opcode == NVME_CMD_WRITE ? 1 : 0; if ((slba + nlb) > ns->id_ns.nsze) { return NVME_LBA_RANGE | NVME_DNR; } if (nvme_map_prp(&req->qsg, prp1, prp2, data_size, n)) { return NVME_INVALID_FIELD | NVME_DNR; } assert((nlb << data_shift) == req->qsg.size); dma_acct_start(n->conf.bs, &req->acct, &req->qsg, is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ); req->aiocb = is_write ? dma_bdrv_write(n->conf.bs, &req->qsg, aio_slba, nvme_rw_cb, req) : dma_bdrv_read(n->conf.bs, &req->qsg, aio_slba, nvme_rw_cb, req); return NVME_NO_COMPLETE; }


static int decode_block_progressive(MJpegDecodeContext *s, DCTELEM *block, uint8_t *last_nnz, int ac_index, int16_t *quant_matrix, int ss, int se, int Al, int *EOBRUN) { int code, i, j, level, val, run; if(*EOBRUN){ (*EOBRUN)--; return 0; } {OPEN_READER(re, &s->gb) for(i=ss;;i++) { UPDATE_CACHE(re, &s->gb); GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2) /* Progressive JPEG use AC coeffs from zero and this decoder sets offset 16 by default */ code -= 16; run = ((unsigned) code) >> 4; code &= 0xF; if(code) { i += run; if(code > MIN_CACHE_BITS - 16){ UPDATE_CACHE(re, &s->gb) } { int cache=GET_CACHE(re,&s->gb); int sign=(~cache)>>31; level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign; } LAST_SKIP_BITS(re, &s->gb, code) if (i >= se) { if(i == se){ j = s->scantable.permutated[se]; block[j] = level * quant_matrix[j] << Al; break; } av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i); return -1; } j = s->scantable.permutated[i]; block[j] = level * quant_matrix[j] << Al; }else{ if(run == 0xF){// ZRL - skip 15 coefficients i += 15; }else{ val = (1 << run); if(run){ UPDATE_CACHE(re, &s->gb); val += NEG_USR32(GET_CACHE(re, &s->gb), run); LAST_SKIP_BITS(re, &s->gb, run); } *EOBRUN = val - 1; break; } } } CLOSE_READER(re, &s->gb)} if(i > *last_nnz) *last_nnz = i; return 0; }


static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) { /* Primary audio coding side information */ int j, k; if (get_bits_left(&s->gb) < 0) return AVERROR_INVALIDDATA; if (!base_channel) { s->subsubframes[s->current_subframe] = get_bits(&s->gb, 2) + 1; s->partial_samples[s->current_subframe] = get_bits(&s->gb, 3); } for (j = base_channel; j < s->prim_channels; j++) { for (k = 0; k < s->subband_activity[j]; k++) s->prediction_mode[j][k] = get_bits(&s->gb, 1); } /* Get prediction codebook */ for (j = base_channel; j < s->prim_channels; j++) { for (k = 0; k < s->subband_activity[j]; k++) { if (s->prediction_mode[j][k] > 0) { /* (Prediction coefficient VQ address) */ s->prediction_vq[j][k] = get_bits(&s->gb, 12); } } } /* Bit allocation index */ for (j = base_channel; j < s->prim_channels; j++) { for (k = 0; k < s->vq_start_subband[j]; k++) { if (s->bitalloc_huffman[j] == 6) s->bitalloc[j][k] = get_bits(&s->gb, 5); else if (s->bitalloc_huffman[j] == 5) s->bitalloc[j][k] = get_bits(&s->gb, 4); else if (s->bitalloc_huffman[j] == 7) { av_log(s->avctx, AV_LOG_ERROR, "Invalid bit allocation index\n"); return AVERROR_INVALIDDATA; } else { s->bitalloc[j][k] = get_bitalloc(&s->gb, &dca_bitalloc_index, s->bitalloc_huffman[j]); } if (s->bitalloc[j][k] > 26) { // av_log(s->avctx, AV_LOG_DEBUG, "bitalloc index [%i][%i] too big (%i)\n", // j, k, s->bitalloc[j][k]); return AVERROR_INVALIDDATA; } } } /* Transition mode */ for (j = base_channel; j < s->prim_channels; j++) { for (k = 0; k < s->subband_activity[j]; k++) { s->transition_mode[j][k] = 0; if (s->subsubframes[s->current_subframe] > 1 && k < s->vq_start_subband[j] && s->bitalloc[j][k] > 0) { s->transition_mode[j][k] = get_bitalloc(&s->gb, &dca_tmode, s->transient_huffman[j]); } } } if (get_bits_left(&s->gb) < 0) return AVERROR_INVALIDDATA; for (j = base_channel; j < s->prim_channels; j++) { const uint32_t *scale_table; int scale_sum; memset(s->scale_factor[j], 0, s->subband_activity[j] * sizeof(s->scale_factor[0][0][0]) * 2); if (s->scalefactor_huffman[j] == 6) scale_table = scale_factor_quant7; else scale_table = scale_factor_quant6; /* When huffman coded, only the difference is encoded */ scale_sum = 0; for (k = 0; k < s->subband_activity[j]; k++) { if (k >= s->vq_start_subband[j] || s->bitalloc[j][k] > 0) { scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum); s->scale_factor[j][k][0] = scale_table[scale_sum]; } if (k < s->vq_start_subband[j] && s->transition_mode[j][k]) { /* Get second scale factor */ scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum); s->scale_factor[j][k][1] = scale_table[scale_sum]; } } } /* Joint subband scale factor codebook select */ for (j = base_channel; j < s->prim_channels; j++) { /* Transmitted only if joint subband coding enabled */ if (s->joint_intensity[j] > 0) s->joint_huff[j] = get_bits(&s->gb, 3); } if (get_bits_left(&s->gb) < 0) return AVERROR_INVALIDDATA; /* Scale factors for joint subband coding */ for (j = base_channel; j < s->prim_channels; j++) { int source_channel; /* Transmitted only if joint subband coding enabled */ if (s->joint_intensity[j] > 0) { int scale = 0; source_channel = s->joint_intensity[j] - 1; /* When huffman coded, only the difference is encoded * (is this valid as well for joint scales ???) */ for (k = s->subband_activity[j]; k < s->subband_activity[source_channel]; k++) { scale = get_scale(&s->gb, s->joint_huff[j], 0); scale += 64; /* bias */ s->joint_scale_factor[j][k] = scale; /*joint_scale_table[scale]; */ } if (!(s->debug_flag & 0x02)) { av_log(s->avctx, AV_LOG_DEBUG, "Joint stereo coding not supported\n"); s->debug_flag |= 0x02; } } } /* Stereo downmix coefficients */ if (!base_channel && s->prim_channels > 2) { if (s->downmix) { for (j = base_channel; j < s->prim_channels; j++) { s->downmix_coef[j][0] = get_bits(&s->gb, 7); s->downmix_coef[j][1] = get_bits(&s->gb, 7); } } else { int am = s->amode & DCA_CHANNEL_MASK; for (j = base_channel; j < s->prim_channels; j++) { s->downmix_coef[j][0] = dca_default_coeffs[am][j][0]; s->downmix_coef[j][1] = dca_default_coeffs[am][j][1]; } } } /* Dynamic range coefficient */ if (!base_channel && s->dynrange) s->dynrange_coef = get_bits(&s->gb, 8); /* Side information CRC check word */ if (s->crc_present) { get_bits(&s->gb, 16); } /* * Primary audio data arrays */ /* VQ encoded high frequency subbands */ for (j = base_channel; j < s->prim_channels; j++) for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) /* 1 vector -> 32 samples */ s->high_freq_vq[j][k] = get_bits(&s->gb, 10); /* Low frequency effect data */ if (!base_channel && s->lfe) { /* LFE samples */ int lfe_samples = 2 * s->lfe * (4 + block_index); int lfe_end_sample = 2 * s->lfe * (4 + block_index + s->subsubframes[s->current_subframe]); float lfe_scale; for (j = lfe_samples; j < lfe_end_sample; j++) { /* Signed 8 bits int */ s->lfe_data[j] = get_sbits(&s->gb, 8); } /* Scale factor index */ s->lfe_scale_factor = scale_factor_quant7[get_bits(&s->gb, 8)]; /* Quantization step size * scale factor */ lfe_scale = 0.035 * s->lfe_scale_factor; for (j = lfe_samples; j < lfe_end_sample; j++) s->lfe_data[j] *= lfe_scale; } #ifdef TRACE av_log(s->avctx, AV_LOG_DEBUG, "subsubframes: %i\n", s->subsubframes[s->current_subframe]); av_log(s->avctx, AV_LOG_DEBUG, "partial samples: %i\n", s->partial_samples[s->current_subframe]); for (j = base_channel; j < s->prim_channels; j++) { av_log(s->avctx, AV_LOG_DEBUG, "prediction mode:"); for (k = 0; k < s->subband_activity[j]; k++) av_log(s->avctx, AV_LOG_DEBUG, " %i", s->prediction_mode[j][k]); av_log(s->avctx, AV_LOG_DEBUG, "\n"); } for (j = base_channel; j < s->prim_channels; j++) { for (k = 0; k < s->subband_activity[j]; k++) av_log(s->avctx, AV_LOG_DEBUG, "prediction coefs: %f, %f, %f, %f\n", (float) adpcm_vb[s->prediction_vq[j][k]][0] / 8192, (float) adpcm_vb[s->prediction_vq[j][k]][1] / 8192, (float) adpcm_vb[s->prediction_vq[j][k]][2] / 8192, (float) adpcm_vb[s->prediction_vq[j][k]][3] / 8192); } for (j = base_channel; j < s->prim_channels; j++) { av_log(s->avctx, AV_LOG_DEBUG, "bitalloc index: "); for (k = 0; k < s->vq_start_subband[j]; k++) av_log(s->avctx, AV_LOG_DEBUG, "%2.2i ", s->bitalloc[j][k]); av_log(s->avctx, AV_LOG_DEBUG, "\n"); } for (j = base_channel; j < s->prim_channels; j++) { av_log(s->avctx, AV_LOG_DEBUG, "Transition mode:"); for (k = 0; k < s->subband_activity[j]; k++) av_log(s->avctx, AV_LOG_DEBUG, " %i", s->transition_mode[j][k]); av_log(s->avctx, AV_LOG_DEBUG, "\n"); } for (j = base_channel; j < s->prim_channels; j++) { av_log(s->avctx, AV_LOG_DEBUG, "Scale factor:"); for (k = 0; k < s->subband_activity[j]; k++) { if (k >= s->vq_start_subband[j] || s->bitalloc[j][k] > 0) av_log(s->avctx, AV_LOG_DEBUG, " %i", s->scale_factor[j][k][0]); if (k < s->vq_start_subband[j] && s->transition_mode[j][k]) av_log(s->avctx, AV_LOG_DEBUG, " %i(t)", s->scale_factor[j][k][1]); } av_log(s->avctx, AV_LOG_DEBUG, "\n"); } for (j = base_channel; j < s->prim_channels; j++) { if (s->joint_intensity[j] > 0) { int source_channel = s->joint_intensity[j] - 1; av_log(s->avctx, AV_LOG_DEBUG, "Joint scale factor index:\n"); for (k = s->subband_activity[j]; k < s->subband_activity[source_channel]; k++) av_log(s->avctx, AV_LOG_DEBUG, " %i", s->joint_scale_factor[j][k]); av_log(s->avctx, AV_LOG_DEBUG, "\n"); } } if (!base_channel && s->prim_channels > 2 && s->downmix) { av_log(s->avctx, AV_LOG_DEBUG, "Downmix coeffs:\n"); for (j = 0; j < s->prim_channels; j++) { av_log(s->avctx, AV_LOG_DEBUG, "Channel 0, %d = %f\n", j, dca_downmix_coeffs[s->downmix_coef[j][0]]); av_log(s->avctx, AV_LOG_DEBUG, "Channel 1, %d = %f\n", j, dca_downmix_coeffs[s->downmix_coef[j][1]]); } av_log(s->avctx, AV_LOG_DEBUG, "\n"); } for (j = base_channel; j < s->prim_channels; j++) for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) av_log(s->avctx, AV_LOG_DEBUG, "VQ index: %i\n", s->high_freq_vq[j][k]); if (!base_channel && s->lfe) { int lfe_samples = 2 * s->lfe * (4 + block_index); int lfe_end_sample = 2 * s->lfe * (4 + block_index + s->subsubframes[s->current_subframe]); av_log(s->avctx, AV_LOG_DEBUG, "LFE samples:\n"); for (j = lfe_samples; j < lfe_end_sample; j++) av_log(s->avctx, AV_LOG_DEBUG, " %f", s->lfe_data[j]); av_log(s->avctx, AV_LOG_DEBUG, "\n"); } #endif return 0; }


static int vc1_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; VC1Context *v = avctx->priv_data; MpegEncContext *s = &v->s; AVFrame *pict = data; uint8_t *buf2 = NULL; const uint8_t *buf_start = buf; /* no supplementary picture */ if (buf_size == 0) { /* special case for last picture */ if (s->low_delay==0 && s->next_picture_ptr) { *pict= *(AVFrame*)s->next_picture_ptr; s->next_picture_ptr= NULL; *data_size = sizeof(AVFrame); } return 0; } /* We need to set current_picture_ptr before reading the header, * otherwise we cannot store anything in there. */ if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ int i= ff_find_unused_picture(s, 0); s->current_picture_ptr= &s->picture[i]; } if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){ if (v->profile < PROFILE_ADVANCED) avctx->pix_fmt = PIX_FMT_VDPAU_WMV3; else avctx->pix_fmt = PIX_FMT_VDPAU_VC1; } //for advanced profile we may need to parse and unescape data if (avctx->codec_id == CODEC_ID_VC1) { int buf_size2 = 0; buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if(IS_MARKER(AV_RB32(buf))){ /* frame starts with marker and needs to be parsed */ const uint8_t *start, *end, *next; int size; next = buf; for(start = buf, end = buf + buf_size; next < end; start = next){ next = find_next_marker(start + 4, end); size = next - start - 4; if(size <= 0) continue; switch(AV_RB32(start)){ case VC1_CODE_FRAME: if (avctx->hwaccel || s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) buf_start = start; buf_size2 = vc1_unescape_buffer(start + 4, size, buf2); break; case VC1_CODE_ENTRYPOINT: /* it should be before frame data */ buf_size2 = vc1_unescape_buffer(start + 4, size, buf2); init_get_bits(&s->gb, buf2, buf_size2*8); vc1_decode_entry_point(avctx, v, &s->gb); break; case VC1_CODE_SLICE: av_log(avctx, AV_LOG_ERROR, "Sliced decoding is not implemented (yet)\n"); av_free(buf2); return -1; } } }else if(v->interlace && ((buf[0] & 0xC0) == 0xC0)){ /* WVC1 interlaced stores both fields divided by marker */ const uint8_t *divider; divider = find_next_marker(buf, buf + buf_size); if((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD){ av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n"); av_free(buf2); return -1; } buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2); // TODO av_free(buf2);return -1; }else{ buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2); } init_get_bits(&s->gb, buf2, buf_size2*8); } else init_get_bits(&s->gb, buf, buf_size*8); // do parse frame header if(v->profile < PROFILE_ADVANCED) { if(vc1_parse_frame_header(v, &s->gb) == -1) { av_free(buf2); return -1; } } else { if(vc1_parse_frame_header_adv(v, &s->gb) == -1) { av_free(buf2); return -1; } } if(s->pict_type != FF_I_TYPE && !v->res_rtm_flag){ av_free(buf2); return -1; } // for hurry_up==5 s->current_picture.pict_type= s->pict_type; s->current_picture.key_frame= s->pict_type == FF_I_TYPE; /* skip B-frames if we don't have reference frames */ if(s->last_picture_ptr==NULL && (s->pict_type==FF_B_TYPE || s->dropable)){ av_free(buf2); return -1;//buf_size; } /* skip b frames if we are in a hurry */ if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return -1;//buf_size; if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==FF_B_TYPE) || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_I_TYPE) || avctx->skip_frame >= AVDISCARD_ALL) { av_free(buf2); return buf_size; } /* skip everything if we are in a hurry>=5 */ if(avctx->hurry_up>=5) { av_free(buf2); return -1;//buf_size; } if(s->next_p_frame_damaged){ if(s->pict_type==FF_B_TYPE) return buf_size; else s->next_p_frame_damaged=0; } if(MPV_frame_start(s, avctx) < 0) { av_free(buf2); return -1; } s->me.qpel_put= s->dsp.put_qpel_pixels_tab; s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab; if ((CONFIG_VC1_VDPAU_DECODER || CONFIG_WMV3_VDPAU_DECODER) &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start); else if (avctx->hwaccel) { if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0) return -1; if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0) return -1; if (avctx->hwaccel->end_frame(avctx) < 0) return -1; } else { ff_er_frame_start(s); v->bits = buf_size * 8; vc1_decode_blocks(v); //av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), buf_size*8); // if(get_bits_count(&s->gb) > buf_size * 8) // return -1; ff_er_frame_end(s); } MPV_frame_end(s); assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type); assert(s->current_picture.pict_type == s->pict_type); if (s->pict_type == FF_B_TYPE || s->low_delay) { *pict= *(AVFrame*)s->current_picture_ptr; } else if (s->last_picture_ptr != NULL) { *pict= *(AVFrame*)s->last_picture_ptr; } if(s->last_picture_ptr || s->low_delay){ *data_size = sizeof(AVFrame); ff_print_debug_info(s, pict); } av_free(buf2); return buf_size; }


static void ff_h264_idct_add8_mmx2(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ int i; for(i=16; i<16+8; i++){ if(nnzc[ scan8[i] ]) ff_h264_idct_add_mmx (dest[(i&4)>>2] + block_offset[i], block + i*16, stride); else if(block[i*16]) ff_h264_idct_dc_add_mmx2(dest[(i&4)>>2] + block_offset[i], block + i*16, stride); } }


int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) { if (len > 6) { /* check for h264 start code */ if (AV_RB32(data) == 0x00000001 || AV_RB24(data) == 0x000001) { uint8_t *buf=NULL, *end, *start; uint32_t sps_size=0, pps_size=0; uint8_t *sps=0, *pps=0; int ret = ff_avc_parse_nal_units_buf(data, &buf, &len); if (ret < 0) return ret; start = buf; end = buf + len; /* look for sps and pps */ while (buf < end) { unsigned int size; uint8_t nal_type; size = AV_RB32(buf); nal_type = buf[4] & 0x1f; if (nal_type == 7) { /* SPS */ sps = buf + 4; sps_size = size; } else if (nal_type == 8) { /* PPS */ pps = buf + 4; pps_size = size; } buf += size + 4; } assert(sps); assert(pps); avio_w8(pb, 1); /* version */ avio_w8(pb, sps[1]); /* profile */ avio_w8(pb, sps[2]); /* profile compat */ avio_w8(pb, sps[3]); /* level */ avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */ avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */ avio_wb16(pb, sps_size); avio_write(pb, sps, sps_size); avio_w8(pb, 1); /* number of pps */ avio_wb16(pb, pps_size); avio_write(pb, pps, pps_size); av_free(start); } else { avio_write(pb, data, len); } } return 0; }


static void uninit(struct vf_instance *vf) { free(vf->priv); }


static ExitStatus trans_fop_dew_0c(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned rt = extract32(insn, 0, 5); unsigned ra = extract32(insn, 21, 5); return do_fop_dew(ctx, rt, ra, di->f_dew); }


static void test_dispatch_cmd_io(void) { QDict *req = qdict_new(); QDict *args = qdict_new(); QDict *args3 = qdict_new(); QDict *ud1a = qdict_new(); QDict *ud1b = qdict_new(); QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef; QDict *ret_dict_dict2, *ret_dict_dict2_userdef; QInt *ret3; qdict_put_obj(ud1a, "integer", QOBJECT(qint_from_int(42))); qdict_put_obj(ud1a, "string", QOBJECT(qstring_from_str("hello"))); qdict_put_obj(ud1b, "integer", QOBJECT(qint_from_int(422))); qdict_put_obj(ud1b, "string", QOBJECT(qstring_from_str("hello2"))); qdict_put_obj(args, "ud1a", QOBJECT(ud1a)); qdict_put_obj(args, "ud1b", QOBJECT(ud1b)); qdict_put_obj(req, "arguments", QOBJECT(args)); qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2"))); ret = qobject_to_qdict(test_qmp_dispatch(req)); assert(!strcmp(qdict_get_str(ret, "string"), "blah1")); ret_dict = qdict_get_qdict(ret, "dict"); assert(!strcmp(qdict_get_str(ret_dict, "string"), "blah2")); ret_dict_dict = qdict_get_qdict(ret_dict, "dict"); ret_dict_dict_userdef = qdict_get_qdict(ret_dict_dict, "userdef"); assert(qdict_get_int(ret_dict_dict_userdef, "integer") == 42); assert(!strcmp(qdict_get_str(ret_dict_dict_userdef, "string"), "hello")); assert(!strcmp(qdict_get_str(ret_dict_dict, "string"), "blah3")); ret_dict_dict2 = qdict_get_qdict(ret_dict, "dict2"); ret_dict_dict2_userdef = qdict_get_qdict(ret_dict_dict2, "userdef"); assert(qdict_get_int(ret_dict_dict2_userdef, "integer") == 422); assert(!strcmp(qdict_get_str(ret_dict_dict2_userdef, "string"), "hello2")); assert(!strcmp(qdict_get_str(ret_dict_dict2, "string"), "blah4")); QDECREF(ret); qdict_put(args3, "a", qint_from_int(66)); qdict_put(req, "arguments", args3); qdict_put(req, "execute", qstring_from_str("user_def_cmd3")); ret3 = qobject_to_qint(test_qmp_dispatch(req)); assert(qint_get_int(ret3) == 66); QDECREF(ret); QDECREF(req); }


int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { BdrvTrackedRequest req; int max_discard, ret; if (!bs->drv) { return -ENOMEDIUM; } ret = bdrv_check_request(bs, sector_num, nb_sectors); if (ret < 0) { return ret; } else if (bs->read_only) { return -EPERM; } assert(!(bs->open_flags & BDRV_O_INACTIVE)); /* Do nothing if disabled. */ if (!(bs->open_flags & BDRV_O_UNMAP)) { return 0; } if (!bs->drv->bdrv_co_discard && !bs->drv->bdrv_aio_discard) { return 0; } tracked_request_begin(&req, bs, sector_num << BDRV_SECTOR_BITS, nb_sectors << BDRV_SECTOR_BITS, BDRV_TRACKED_DISCARD); ret = notifier_with_return_list_notify(&bs->before_write_notifiers, &req); if (ret < 0) { goto out; } max_discard = MIN_NON_ZERO(bs->bl.max_pdiscard >> BDRV_SECTOR_BITS, BDRV_REQUEST_MAX_SECTORS); while (nb_sectors > 0) { int ret; int num = nb_sectors; int discard_alignment = bs->bl.pdiscard_alignment >> BDRV_SECTOR_BITS; /* align request */ if (discard_alignment && num >= discard_alignment && sector_num % discard_alignment) { if (num > discard_alignment) { num = discard_alignment; } num -= sector_num % discard_alignment; } /* limit request size */ if (num > max_discard) { num = max_discard; } if (bs->drv->bdrv_co_discard) { ret = bs->drv->bdrv_co_discard(bs, sector_num, num); } else { BlockAIOCB *acb; CoroutineIOCompletion co = { .coroutine = qemu_coroutine_self(), }; acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors, bdrv_co_io_em_complete, &co); if (acb == NULL) { ret = -EIO; goto out; } else { qemu_coroutine_yield(); ret = co.ret; } } if (ret && ret != -ENOTSUP) { goto out; } sector_num += num; nb_sectors -= num; } ret = 0; out: bdrv_set_dirty(bs, req.offset >> BDRV_SECTOR_BITS, req.bytes >> BDRV_SECTOR_BITS); tracked_request_end(&req); return ret; }


static CCW1 copy_ccw_from_guest(hwaddr addr, bool fmt1) { CCW0 tmp0; CCW1 tmp1; CCW1 ret; if (fmt1) { cpu_physical_memory_read(addr, &tmp1, sizeof(tmp1)); ret.cmd_code = tmp1.cmd_code; ret.flags = tmp1.flags; ret.count = be16_to_cpu(tmp1.count); ret.cda = be32_to_cpu(tmp1.cda); } else { cpu_physical_memory_read(addr, &tmp0, sizeof(tmp0)); ret.cmd_code = tmp0.cmd_code; ret.flags = tmp0.flags; ret.count = be16_to_cpu(tmp0.count); ret.cda = be16_to_cpu(tmp0.cda1) | (tmp0.cda0 << 16); if ((ret.cmd_code & 0x0f) == CCW_CMD_TIC) { ret.cmd_code &= 0x0f; } } return ret; }


static int tosa_dac_init(I2CSlave *i2c) { /* Nothing to do. */ return 0; }


CharDriverState *qemu_chr_open_eventfd(int eventfd) { CharDriverState *chr = qemu_chr_open_fd(eventfd, eventfd); if (chr) { chr->avail_connections = 1; } return chr; }


static CharDriverState *qmp_chardev_open_socket(const char *id, ChardevBackend *backend, ChardevReturn *ret, Error **errp) { CharDriverState *chr; TCPCharDriver *s; ChardevSocket *sock = backend->u.socket; SocketAddress *addr = sock->addr; bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; bool is_listen = sock->has_server ? sock->server : true; bool is_telnet = sock->has_telnet ? sock->telnet : false; bool is_waitconnect = sock->has_wait ? sock->wait : false; int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0; ChardevCommon *common = qapi_ChardevSocket_base(sock); QIOChannelSocket *sioc = NULL; chr = qemu_chr_alloc(common, errp); if (!chr) { return NULL; } s = g_new0(TCPCharDriver, 1); s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX; s->is_listen = is_listen; s->is_telnet = is_telnet; s->do_nodelay = do_nodelay; if (sock->tls_creds) { Object *creds; creds = object_resolve_path_component( object_get_objects_root(), sock->tls_creds); if (!creds) { error_setg(errp, "No TLS credentials with id '%s'", sock->tls_creds); goto error; } s->tls_creds = (QCryptoTLSCreds *) object_dynamic_cast(creds, TYPE_QCRYPTO_TLS_CREDS); if (!s->tls_creds) { error_setg(errp, "Object with id '%s' is not TLS credentials", sock->tls_creds); goto error; } object_ref(OBJECT(s->tls_creds)); if (is_listen) { if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { error_setg(errp, "%s", "Expected TLS credentials for server endpoint"); goto error; } } else { if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) { error_setg(errp, "%s", "Expected TLS credentials for client endpoint"); goto error; } } } qapi_copy_SocketAddress(&s->addr, sock->addr); chr->opaque = s; chr->chr_write = tcp_chr_write; chr->chr_sync_read = tcp_chr_sync_read; chr->chr_close = tcp_chr_close; chr->get_msgfds = tcp_get_msgfds; chr->set_msgfds = tcp_set_msgfds; chr->chr_add_client = tcp_chr_add_client; chr->chr_add_watch = tcp_chr_add_watch; chr->chr_update_read_handler = tcp_chr_update_read_handler; /* be isn't opened until we get a connection */ chr->explicit_be_open = true; chr->filename = SocketAddress_to_str("disconnected:", addr, is_listen, is_telnet); if (is_listen) { if (is_telnet) { s->do_telnetopt = 1; } } else if (reconnect > 0) { s->reconnect_time = reconnect; } sioc = qio_channel_socket_new(); if (s->reconnect_time) { qio_channel_socket_connect_async(sioc, s->addr, qemu_chr_socket_connected, chr, NULL); } else if (s->is_listen) { if (qio_channel_socket_listen_sync(sioc, s->addr, errp) < 0) { goto error; } s->listen_ioc = sioc; if (is_waitconnect) { fprintf(stderr, "QEMU waiting for connection on: %s\n", chr->filename); tcp_chr_accept(QIO_CHANNEL(s->listen_ioc), G_IO_IN, chr); } qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), false, NULL); if (!s->ioc) { s->listen_tag = qio_channel_add_watch( QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL); } } else { if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) { goto error; } tcp_chr_new_client(chr, sioc); object_unref(OBJECT(sioc)); } return chr; error: if (sioc) { object_unref(OBJECT(sioc)); } if (s->tls_creds) { object_unref(OBJECT(s->tls_creds)); } g_free(s); qemu_chr_free_common(chr); return NULL; }


uint64_t ldq_le_phys(target_phys_addr_t addr) { return ldq_phys_internal(addr, DEVICE_LITTLE_ENDIAN); }


static int rv10_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MpegEncContext *s = avctx->priv_data; AVFrame *pict = data; int i, ret; int slice_count; const uint8_t *slices_hdr = NULL; av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size); /* no supplementary picture */ if (buf_size == 0) { return 0; } if (!avctx->slice_count) { slice_count = (*buf++) + 1; buf_size--; if (!slice_count || buf_size <= 8 * slice_count) { av_log(avctx, AV_LOG_ERROR, "Invalid slice count: %d.\n", slice_count); return AVERROR_INVALIDDATA; } slices_hdr = buf + 4; buf += 8 * slice_count; buf_size -= 8 * slice_count; } else slice_count = avctx->slice_count; for (i = 0; i < slice_count; i++) { unsigned offset = get_slice_offset(avctx, slices_hdr, i); int size, size2; if (offset >= buf_size) return AVERROR_INVALIDDATA; if (i + 1 == slice_count) size = buf_size - offset; else size = get_slice_offset(avctx, slices_hdr, i + 1) - offset; if (i + 2 >= slice_count) size2 = buf_size - offset; else size2 = get_slice_offset(avctx, slices_hdr, i + 2) - offset; if (size <= 0 || size2 <= 0 || offset + FFMAX(size, size2) > buf_size) return AVERROR_INVALIDDATA; if ((ret = rv10_decode_packet(avctx, buf + offset, size, size2)) < 0) return ret; if (ret > 8 * size) i++; } if (s->current_picture_ptr != NULL && s->mb_y >= s->mb_height) { ff_er_frame_end(&s->er); ff_mpv_frame_end(s); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0) return ret; ff_print_debug_info(s, s->current_picture_ptr); } else if (s->last_picture_ptr != NULL) { if ((ret = av_frame_ref(pict, s->last_picture_ptr->f)) < 0) return ret; ff_print_debug_info(s, s->last_picture_ptr); } if (s->last_picture_ptr || s->low_delay) { *got_frame = 1; } // so we can detect if frame_end was not called (find some nicer solution...) s->current_picture_ptr = NULL; } return avpkt->size; }


void xen_config_cleanup(void) { struct xs_dirs *d; TAILQ_FOREACH(d, &xs_cleanup, list) { xs_rm(xenstore, 0, d->xs_dir); } }


uint64_t helper_frsqrte(CPUPPCState *env, uint64_t arg) { CPU_DoubleU farg; farg.ll = arg; if (unlikely(float64_is_neg(farg.d) && !float64_is_zero(farg.d))) { /* Reciprocal square root of a negative nonzero number */ farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1); } else { if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN reciprocal square root */ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); } farg.d = float64_sqrt(farg.d, &env->fp_status); farg.d = float64_div(float64_one, farg.d, &env->fp_status); } return farg.ll; }


static MemTxResult vtd_mem_ir_write(void *opaque, hwaddr addr, uint64_t value, unsigned size, MemTxAttrs attrs) { int ret = 0; MSIMessage from = {}, to = {}; from.address = (uint64_t) addr + VTD_INTERRUPT_ADDR_FIRST; from.data = (uint32_t) value; ret = vtd_interrupt_remap_msi(opaque, &from, &to); if (ret) { /* TODO: report error */ VTD_DPRINTF(GENERAL, "int remap fail for addr 0x%"PRIx64 " data 0x%"PRIx32, from.address, from.data); /* Drop this interrupt */ return MEMTX_ERROR; } VTD_DPRINTF(IR, "delivering MSI 0x%"PRIx64":0x%"PRIx32 " for device sid 0x%04x", to.address, to.data, sid); if (dma_memory_write(&address_space_memory, to.address, &to.data, size)) { VTD_DPRINTF(GENERAL, "error: fail to write 0x%"PRIx64 " value 0x%"PRIx32, to.address, to.data); } return MEMTX_OK; }


static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, int64_t offset_in_cluster, QEMUIOVector *qiov, int bytes) { int ret; int cluster_bytes, buf_bytes; uint8_t *cluster_buf, *compressed_data; uint8_t *uncomp_buf; uint32_t data_len; VmdkGrainMarker *marker; uLongf buf_len; if (!extent->compressed) { ret = bdrv_co_preadv(extent->file->bs, cluster_offset + offset_in_cluster, bytes, qiov, 0); if (ret < 0) { return ret; } return 0; } cluster_bytes = extent->cluster_sectors * 512; /* Read two clusters in case GrainMarker + compressed data > one cluster */ buf_bytes = cluster_bytes * 2; cluster_buf = g_malloc(buf_bytes); uncomp_buf = g_malloc(cluster_bytes); ret = bdrv_pread(extent->file, cluster_offset, cluster_buf, buf_bytes); if (ret < 0) { goto out; } compressed_data = cluster_buf; buf_len = cluster_bytes; data_len = cluster_bytes; if (extent->has_marker) { marker = (VmdkGrainMarker *)cluster_buf; compressed_data = marker->data; data_len = le32_to_cpu(marker->size); } if (!data_len || data_len > buf_bytes) { ret = -EINVAL; goto out; } ret = uncompress(uncomp_buf, &buf_len, compressed_data, data_len); if (ret != Z_OK) { ret = -EINVAL; goto out; } if (offset_in_cluster < 0 || offset_in_cluster + bytes > buf_len) { ret = -EINVAL; goto out; } qemu_iovec_from_buf(qiov, 0, uncomp_buf + offset_in_cluster, bytes); ret = 0; out: g_free(uncomp_buf); g_free(cluster_buf); return ret; }


static void parser_context_free(JSONParserContext *ctxt) { if (ctxt) { while (!g_queue_is_empty(ctxt->buf)) { parser_context_pop_token(ctxt); } qobject_decref(ctxt->current); g_queue_free(ctxt->buf); g_free(ctxt); } }


int page_check_range(target_ulong start, target_ulong len, int flags) { PageDesc *p; target_ulong end; target_ulong addr; if (start + len < start) /* we've wrapped around */ return -1; end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the next step */ start = start & TARGET_PAGE_MASK; for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { p = page_find(addr >> TARGET_PAGE_BITS); if( !p ) return -1; if( !(p->flags & PAGE_VALID) ) return -1; if ((flags & PAGE_READ) && !(p->flags & PAGE_READ)) return -1; if (flags & PAGE_WRITE) { if (!(p->flags & PAGE_WRITE_ORG)) return -1; /* unprotect the page if it was put read-only because it contains translated code */ if (!(p->flags & PAGE_WRITE)) { if (!page_unprotect(addr, 0, NULL)) return -1; } return 0; } } return 0; }


processed(OptsVisitor *ov, const char *name) { if (ov->repeated_opts == NULL) { g_hash_table_remove(ov->unprocessed_opts, name); } }


minimac2_read(void *opaque, target_phys_addr_t addr, unsigned size) { MilkymistMinimac2State *s = opaque; uint32_t r = 0; addr >>= 2; switch (addr) { case R_SETUP: case R_MDIO: case R_STATE0: case R_COUNT0: case R_STATE1: case R_COUNT1: case R_TXCOUNT: r = s->regs[addr]; break; default: error_report("milkymist_minimac2: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } trace_milkymist_minimac2_memory_read(addr << 2, r); return r; }


static inline void float_to_int (float * _f, int16_t * s16, int samples) { int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format int i; for (i = 0; i < samples; i++) { s16[i] = blah (f[i]); } }


void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid) { KVMDevice *kd; if (!kvm_irqchip_in_kernel()) { return; } if (QSLIST_EMPTY(&kvm_devices_head)) { memory_listener_register(&devlistener, NULL); qemu_add_machine_init_done_notifier(&notify); } kd = g_new0(KVMDevice, 1); kd->mr = mr; kd->kda.id = devid; kd->kda.addr = -1; QSLIST_INSERT_HEAD(&kvm_devices_head, kd, entries); memory_region_ref(kd->mr); }


X86CPU *cpu_x86_init(const char *cpu_model) { X86CPU *cpu; CPUX86State *env; static int inited; cpu = X86_CPU(object_new(TYPE_X86_CPU)); env = &cpu->env; env->cpu_model_str = cpu_model; /* init various static tables used in TCG mode */ if (tcg_enabled() && !inited) { inited = 1; optimize_flags_init(); #ifndef CONFIG_USER_ONLY prev_debug_excp_handler = cpu_set_debug_excp_handler(breakpoint_handler); #endif } if (cpu_x86_register(cpu, cpu_model) < 0) { object_delete(OBJECT(cpu)); return NULL; } x86_cpu_realize(OBJECT(cpu), NULL); return cpu; }


int raw_get_aio_fd(BlockDriverState *bs) { BDRVRawState *s; if (!bs->drv) { return -ENOMEDIUM; } if (bs->drv == bdrv_find_format("raw")) { bs = bs->file; } /* raw-posix has several protocols so just check for raw_aio_readv */ if (bs->drv->bdrv_aio_readv != raw_aio_readv) { return -ENOTSUP; } s = bs->opaque; if (!s->use_aio) { return -ENOTSUP; } return s->fd; }


static SocketAddressLegacy *unix_build_address(const char *path) { SocketAddressLegacy *saddr; saddr = g_new0(SocketAddressLegacy, 1); saddr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX; saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1); saddr->u.q_unix.data->path = g_strdup(path); return saddr; }


e1000_mmio_read(void *opaque, hwaddr addr, unsigned size) { E1000State *s = opaque; unsigned int index = (addr & 0x1ffff) >> 2; if (index < NREADOPS && macreg_readops[index]) { return macreg_readops[index](s, index); } DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2); return 0; }


void bdrv_img_create(const char *filename, const char *fmt, const char *base_filename, const char *base_fmt, char *options, uint64_t img_size, int flags, Error **errp, bool quiet) { QEMUOptionParameter *param = NULL, *create_options = NULL; QEMUOptionParameter *backing_fmt, *backing_file, *size; BlockDriverState *bs = NULL; BlockDriver *drv, *proto_drv; BlockDriver *backing_drv = NULL; int ret = 0; /* Find driver and parse its options */ drv = bdrv_find_format(fmt); if (!drv) { error_setg(errp, "Unknown file format '%s'", fmt); return; } proto_drv = bdrv_find_protocol(filename); if (!proto_drv) { error_setg(errp, "Unknown protocol '%s'", filename); return; } create_options = append_option_parameters(create_options, drv->create_options); create_options = append_option_parameters(create_options, proto_drv->create_options); /* Create parameter list with default values */ param = parse_option_parameters("", create_options, param); set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size); /* Parse -o options */ if (options) { param = parse_option_parameters(options, create_options, param); if (param == NULL) { error_setg(errp, "Invalid options for file format '%s'.", fmt); goto out; } } if (base_filename) { if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE, base_filename)) { error_setg(errp, "Backing file not supported for file format '%s'", fmt); goto out; } } if (base_fmt) { if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) { error_setg(errp, "Backing file format not supported for file " "format '%s'", fmt); goto out; } } backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE); if (backing_file && backing_file->value.s) { if (!strcmp(filename, backing_file->value.s)) { error_setg(errp, "Error: Trying to create an image with the " "same filename as the backing file"); goto out; } } backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT); if (backing_fmt && backing_fmt->value.s) { backing_drv = bdrv_find_format(backing_fmt->value.s); if (!backing_drv) { error_setg(errp, "Unknown backing file format '%s'", backing_fmt->value.s); goto out; } } // The size for the image must always be specified, with one exception: // If we are using a backing file, we can obtain the size from there size = get_option_parameter(param, BLOCK_OPT_SIZE); if (size && size->value.n == -1) { if (backing_file && backing_file->value.s) { uint64_t size; char buf[32]; int back_flags; /* backing files always opened read-only */ back_flags = flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); bs = bdrv_new(""); ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags, backing_drv); if (ret < 0) { error_setg_errno(errp, -ret, "Could not open '%s'", backing_file->value.s); goto out; } bdrv_get_geometry(bs, &size); size *= 512; snprintf(buf, sizeof(buf), "%" PRId64, size); set_option_parameter(param, BLOCK_OPT_SIZE, buf); } else { error_setg(errp, "Image creation needs a size parameter"); goto out; } } if (!quiet) { printf("Formatting '%s', fmt=%s ", filename, fmt); print_option_parameters(param); puts(""); } ret = bdrv_create(drv, filename, param); if (ret < 0) { if (ret == -ENOTSUP) { error_setg(errp,"Formatting or formatting option not supported for " "file format '%s'", fmt); } else if (ret == -EFBIG) { error_setg(errp, "The image size is too large for file format '%s'", fmt); } else { error_setg(errp, "%s: error while creating %s: %s", filename, fmt, strerror(-ret)); } } out: free_option_parameters(create_options); free_option_parameters(param); if (bs) { bdrv_delete(bs); } }


int nbd_client(int fd) { int ret; int serrno; TRACE("Doing NBD loop"); ret = ioctl(fd, NBD_DO_IT); if (ret == -1 && errno == EPIPE) { /* NBD_DO_IT normally returns EPIPE when someone has disconnected * the socket via NBD_DISCONNECT. We do not want to return 1 in * that case. */ ret = 0; } serrno = errno; TRACE("NBD loop returned %d: %s", ret, strerror(serrno)); TRACE("Clearing NBD queue"); ioctl(fd, NBD_CLEAR_QUE); TRACE("Clearing NBD socket"); ioctl(fd, NBD_CLEAR_SOCK); errno = serrno; return ret; }


static void slirp_init_once(void) { static int initialized; struct hostent *he; char our_name[256]; #ifdef _WIN32 WSADATA Data; #endif if (initialized) { return; } initialized = 1; #ifdef _WIN32 WSAStartup(MAKEWORD(2,0), &Data); atexit(winsock_cleanup); #endif loopback_addr.s_addr = htonl(INADDR_LOOPBACK); /* FIXME: This address may change during runtime */ if (gethostname(our_name, sizeof(our_name)) == 0) { he = gethostbyname(our_name); if (he) { our_addr = *(struct in_addr *)he->h_addr; } } if (our_addr.s_addr == 0) { our_addr = loopback_addr; } /* FIXME: This address may change during runtime */ if (get_dns_addr(&dns_addr) < 0) { dns_addr = loopback_addr; } }


BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp) { return bdrv_named_nodes_list(); }


void backup_start(BlockDriverState *bs, BlockDriverState *target, int64_t speed, MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap, BlockdevOnError on_source_error, BlockdevOnError on_target_error, BlockCompletionFunc *cb, void *opaque, BlockJobTxn *txn, Error **errp) { int64_t len; BlockDriverInfo bdi; int ret; assert(bs); assert(target); assert(cb); if (bs == target) { error_setg(errp, "Source and target cannot be the same"); return; } if (!bdrv_is_inserted(bs)) { error_setg(errp, "Device is not inserted: %s", bdrv_get_device_name(bs)); return; } if (!bdrv_is_inserted(target)) { error_setg(errp, "Device is not inserted: %s", bdrv_get_device_name(target)); return; } if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) { return; } if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) { return; } if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) { if (!sync_bitmap) { error_setg(errp, "must provide a valid bitmap name for " "\"incremental\" sync mode"); return; } /* Create a new bitmap, and freeze/disable this one. */ if (bdrv_dirty_bitmap_create_successor(bs, sync_bitmap, errp) < 0) { return; } } else if (sync_bitmap) { error_setg(errp, "a sync_bitmap was provided to backup_run, " "but received an incompatible sync_mode (%s)", MirrorSyncMode_lookup[sync_mode]); return; } len = bdrv_getlength(bs); if (len < 0) { error_setg_errno(errp, -len, "unable to get length for '%s'", bdrv_get_device_name(bs)); goto error; } BackupBlockJob *job = block_job_create(&backup_job_driver, bs, speed, cb, opaque, errp); if (!job) { goto error; } job->on_source_error = on_source_error; job->on_target_error = on_target_error; job->target = target; job->sync_mode = sync_mode; job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ? sync_bitmap : NULL; /* If there is no backing file on the target, we cannot rely on COW if our * backup cluster size is smaller than the target cluster size. Even for * targets with a backing file, try to avoid COW if possible. */ ret = bdrv_get_info(job->target, &bdi); if (ret < 0 && !target->backing) { error_setg_errno(errp, -ret, "Couldn't determine the cluster size of the target image, " "which has no backing file"); error_append_hint(errp, "Aborting, since this may create an unusable destination image\n"); goto error; } else if (ret < 0 && target->backing) { /* Not fatal; just trudge on ahead. */ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT; } else { job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size); } bdrv_op_block_all(target, job->common.blocker); job->common.len = len; job->common.co = qemu_coroutine_create(backup_run); block_job_txn_add_job(txn, &job->common); qemu_coroutine_enter(job->common.co, job); return; error: if (sync_bitmap) { bdrv_reclaim_dirty_bitmap(bs, sync_bitmap, NULL); } }