Compare commits
46 Commits
v1.4.0-rc1
...
list
Author | SHA1 | Date | |
---|---|---|---|
|
03e94e39ce | ||
|
571f65ec20 | ||
|
71652365c5 | ||
|
9893c80d81 | ||
|
8a8f584008 | ||
|
d36b2b904e | ||
|
d037d6bbbc | ||
|
cc2a90432d | ||
|
91b0a8f334 | ||
|
bd9a8d852c | ||
|
760794f784 | ||
|
7ce4106c21 | ||
|
dada5c7e92 | ||
|
0231ed4f22 | ||
|
6aaa9dae80 | ||
|
ad55ab42d4 | ||
|
4a0e6714b0 | ||
|
30d940875d | ||
|
33ccf6675f | ||
|
da888d37b0 | ||
|
03ec2f8308 | ||
|
58fa432522 | ||
|
d7cd369402 | ||
|
d0bce760e0 | ||
|
5dd6be069b | ||
|
84eac31707 | ||
|
f880defbb0 | ||
|
2c5a7f2011 | ||
|
9ee0cb201e | ||
|
d5f1f286ef | ||
|
49295ebc56 | ||
|
cfdd162866 | ||
|
7216ae3d1a | ||
|
312fd5f290 | ||
|
1a9522cc6e | ||
|
474c21349f | ||
|
2da2e52dce | ||
|
10442558ab | ||
|
70ef6a5b71 | ||
|
fb6d1bbd24 | ||
|
0eb256a217 | ||
|
32ab06bcf1 | ||
|
14f9b664b3 | ||
|
1e89ad5b00 | ||
|
b890492110 | ||
|
0184543814 |
@@ -539,6 +539,7 @@ static int block_save_setup(QEMUFile *f, void *opaque)
|
||||
static int block_save_iterate(QEMUFile *f, void *opaque)
|
||||
{
|
||||
int ret;
|
||||
int64_t last_ftell = qemu_ftell(f);
|
||||
|
||||
DPRINTF("Enter save live iterate submitted %d transferred %d\n",
|
||||
block_mig_state.submitted, block_mig_state.transferred);
|
||||
@@ -569,7 +570,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret) {
|
||||
if (ret < 0) {
|
||||
blk_mig_cleanup();
|
||||
return ret;
|
||||
}
|
||||
@@ -582,7 +583,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
|
||||
|
||||
qemu_put_be64(f, BLK_MIG_FLAG_EOS);
|
||||
|
||||
return 0;
|
||||
return qemu_ftell(f) - last_ftell;
|
||||
}
|
||||
|
||||
static int block_save_complete(QEMUFile *f, void *opaque)
|
||||
@@ -609,7 +610,7 @@ static int block_save_complete(QEMUFile *f, void *opaque)
|
||||
} while (ret == 0);
|
||||
|
||||
blk_mig_cleanup();
|
||||
if (ret) {
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
/* report completion */
|
||||
@@ -624,10 +625,18 @@ static int block_save_complete(QEMUFile *f, void *opaque)
|
||||
|
||||
static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size)
|
||||
{
|
||||
/* Estimate pending number of bytes to send */
|
||||
uint64_t pending = get_remaining_dirty() +
|
||||
block_mig_state.submitted * BLOCK_SIZE +
|
||||
block_mig_state.read_done * BLOCK_SIZE;
|
||||
|
||||
DPRINTF("Enter save live pending %ld\n", get_remaining_dirty());
|
||||
/* Report at least one block pending during bulk phase */
|
||||
if (pending == 0 && !block_mig_state.bulk_completed) {
|
||||
pending = BLOCK_SIZE;
|
||||
}
|
||||
|
||||
return get_remaining_dirty();
|
||||
DPRINTF("Enter save live pending %" PRIu64 "\n", pending);
|
||||
return pending;
|
||||
}
|
||||
|
||||
static int block_load(QEMUFile *f, void *opaque, int version_id)
|
||||
@@ -695,7 +704,7 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
|
||||
(addr == 100) ? '\n' : '\r');
|
||||
fflush(stdout);
|
||||
} else if (!(flags & BLK_MIG_FLAG_EOS)) {
|
||||
fprintf(stderr, "Unknown flags\n");
|
||||
fprintf(stderr, "Unknown block migration flags: %#x\n", flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = qemu_file_get_error(f);
|
||||
|
15
block/curl.c
15
block/curl.c
@@ -34,6 +34,10 @@
|
||||
#define DPRINTF(fmt, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define PROTOCOLS (CURLPROTO_HTTP | CURLPROTO_HTTPS | \
|
||||
CURLPROTO_FTP | CURLPROTO_FTPS | \
|
||||
CURLPROTO_TFTP)
|
||||
|
||||
#define CURL_NUM_STATES 8
|
||||
#define CURL_NUM_ACB 8
|
||||
#define SECTOR_SIZE 512
|
||||
@@ -302,6 +306,17 @@ static CURLState *curl_init_state(BDRVCURLState *s)
|
||||
curl_easy_setopt(state->curl, CURLOPT_ERRORBUFFER, state->errmsg);
|
||||
curl_easy_setopt(state->curl, CURLOPT_FAILONERROR, 1);
|
||||
|
||||
/* Restrict supported protocols to avoid security issues in the more
|
||||
* obscure protocols. For example, do not allow POP3/SMTP/IMAP see
|
||||
* CVE-2013-0249.
|
||||
*
|
||||
* Restricting protocols is only supported from 7.19.4 upwards.
|
||||
*/
|
||||
#if LIBCURL_VERSION_NUM >= 0x071304
|
||||
curl_easy_setopt(state->curl, CURLOPT_PROTOCOLS, PROTOCOLS);
|
||||
curl_easy_setopt(state->curl, CURLOPT_REDIR_PROTOCOLS, PROTOCOLS);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_VERBOSE
|
||||
curl_easy_setopt(state->curl, CURLOPT_VERBOSE, 1);
|
||||
#endif
|
||||
|
@@ -217,7 +217,7 @@ static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename)
|
||||
ret = glfs_init(glfs);
|
||||
if (ret) {
|
||||
error_report("Gluster connection failed for server=%s port=%d "
|
||||
"volume=%s image=%s transport=%s\n", gconf->server, gconf->port,
|
||||
"volume=%s image=%s transport=%s", gconf->server, gconf->port,
|
||||
gconf->volname, gconf->image, gconf->transport);
|
||||
goto out;
|
||||
}
|
||||
|
@@ -1257,9 +1257,43 @@ static int hdev_probe_device(const char *filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_hdev_writable(BDRVRawState *s)
|
||||
{
|
||||
#if defined(BLKROGET)
|
||||
/* Linux block devices can be configured "read-only" using blockdev(8).
|
||||
* This is independent of device node permissions and therefore open(2)
|
||||
* with O_RDWR succeeds. Actual writes fail with EPERM.
|
||||
*
|
||||
* bdrv_open() is supposed to fail if the disk is read-only. Explicitly
|
||||
* check for read-only block devices so that Linux block devices behave
|
||||
* properly.
|
||||
*/
|
||||
struct stat st;
|
||||
int readonly = 0;
|
||||
|
||||
if (fstat(s->fd, &st)) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (!S_ISBLK(st.st_mode)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl(s->fd, BLKROGET, &readonly) < 0) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (readonly) {
|
||||
return -EACCES;
|
||||
}
|
||||
#endif /* defined(BLKROGET) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int ret;
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
if (strstart(filename, "/dev/cdrom", NULL)) {
|
||||
@@ -1300,7 +1334,20 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
return raw_open_common(bs, filename, flags, 0);
|
||||
ret = raw_open_common(bs, filename, flags, 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (flags & BDRV_O_RDWR) {
|
||||
ret = check_hdev_writable(s);
|
||||
if (ret < 0) {
|
||||
raw_close(bs);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
|
2
hmp.c
2
hmp.c
@@ -1365,7 +1365,7 @@ void hmp_chardev_add(Monitor *mon, const QDict *qdict)
|
||||
|
||||
opts = qemu_opts_parse(qemu_find_opts("chardev"), args, 1);
|
||||
if (opts == NULL) {
|
||||
error_setg(&err, "Parsing chardev args failed\n");
|
||||
error_setg(&err, "Parsing chardev args failed");
|
||||
} else {
|
||||
qemu_chr_new_from_opts(opts, NULL, &err);
|
||||
}
|
||||
|
@@ -521,7 +521,7 @@ static int v9fs_request(V9fsProxy *proxy, int type,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error_report("Invalid type %d\n", type);
|
||||
error_report("Invalid type %d", type);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
@@ -343,6 +343,7 @@ static void uart_read_rx_fifo(UartState *s, uint32_t *c)
|
||||
if (!s->rx_count) {
|
||||
s->r[R_SR] |= UART_SR_INTR_REMPTY;
|
||||
}
|
||||
qemu_chr_accept_input(s->chr);
|
||||
} else {
|
||||
*c = 0;
|
||||
s->r[R_SR] |= UART_SR_INTR_REMPTY;
|
||||
|
@@ -936,8 +936,8 @@ retry:
|
||||
/* Retry with host-side MSI. There might be an IRQ conflict and
|
||||
* either the kernel or the device doesn't support sharing. */
|
||||
error_report("Host-side INTx sharing not supported, "
|
||||
"using MSI instead.\n"
|
||||
"Some devices do not to work properly in this mode.");
|
||||
"using MSI instead");
|
||||
error_printf("Some devices do not work properly in this mode.\n");
|
||||
dev->features |= ASSIGNED_DEVICE_PREFER_MSI_MASK;
|
||||
goto retry;
|
||||
}
|
||||
@@ -1903,10 +1903,10 @@ static void assigned_dev_load_option_rom(AssignedDevice *dev)
|
||||
memset(ptr, 0xff, st.st_size);
|
||||
|
||||
if (!fread(ptr, 1, st.st_size, fp)) {
|
||||
error_report("pci-assign: Cannot read from host %s\n"
|
||||
"\tDevice option ROM contents are probably invalid "
|
||||
"(check dmesg).\n\tSkip option ROM probe with rombar=0, "
|
||||
"or load from file with romfile=", rom_file);
|
||||
error_report("pci-assign: Cannot read from host %s", rom_file);
|
||||
error_printf("Device option ROM contents are probably invalid "
|
||||
"(check dmesg).\nSkip option ROM probe with rombar=0, "
|
||||
"or load from file with romfile=\n");
|
||||
memory_region_destroy(&dev->dev.rom);
|
||||
goto close_rom;
|
||||
}
|
||||
|
15
hw/m25p80.c
15
hw/m25p80.c
@@ -184,6 +184,7 @@ static const FlashPartInfo known_devices[] = {
|
||||
|
||||
typedef enum {
|
||||
NOP = 0,
|
||||
WRSR = 0x1,
|
||||
WRDI = 0x4,
|
||||
RDSR = 0x5,
|
||||
WREN = 0x6,
|
||||
@@ -379,6 +380,11 @@ static void complete_collecting_data(Flash *s)
|
||||
case ERASE_SECTOR:
|
||||
flash_erase(s, s->cur_addr, s->cmd_in_progress);
|
||||
break;
|
||||
case WRSR:
|
||||
if (s->write_enable) {
|
||||
s->write_enable = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -443,6 +449,15 @@ static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
break;
|
||||
|
||||
case WRSR:
|
||||
if (s->write_enable) {
|
||||
s->needed_bytes = 1;
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
}
|
||||
break;
|
||||
|
||||
case WRDI:
|
||||
s->write_enable = false;
|
||||
break;
|
||||
|
@@ -1132,7 +1132,7 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)
|
||||
} while (dev);
|
||||
|
||||
if (!bus->route_intx_to_irq) {
|
||||
error_report("PCI: Bug - unimplemented PCI INTx routing (%s)\n",
|
||||
error_report("PCI: Bug - unimplemented PCI INTx routing (%s)",
|
||||
object_get_typename(OBJECT(bus->qbus.parent)));
|
||||
return (PCIINTxRoute) { PCI_INTX_DISABLED, -1 };
|
||||
}
|
||||
|
@@ -129,17 +129,19 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
|
||||
xilinx_timer_create(TIMER_BASEADDR, irq[2], 0, 100 * 1000000);
|
||||
|
||||
/* axi ethernet and dma initialization. */
|
||||
qemu_check_nic_model(&nd_table[0], "xlnx.axi-ethernet");
|
||||
eth0 = qdev_create(NULL, "xlnx.axi-ethernet");
|
||||
dma = qdev_create(NULL, "xlnx.axi-dma");
|
||||
|
||||
/* FIXME: attach to the sysbus instead */
|
||||
object_property_add_child(container_get(qdev_get_machine(), "/unattached"),
|
||||
"xilinx-dma", OBJECT(dma), NULL);
|
||||
|
||||
eth0 = xilinx_axiethernet_create(&nd_table[0], STREAM_SLAVE(dma),
|
||||
0x82780000, irq[3], 0x1000, 0x1000);
|
||||
xilinx_axiethernet_init(eth0, &nd_table[0], STREAM_SLAVE(dma),
|
||||
0x82780000, irq[3], 0x1000, 0x1000);
|
||||
|
||||
xilinx_axiethernetdma_init(dma, STREAM_SLAVE(eth0),
|
||||
0x84600000, irq[1], irq[0], 100 * 1000000);
|
||||
xilinx_axidma_init(dma, STREAM_SLAVE(eth0), 0x84600000, irq[1], irq[0],
|
||||
100 * 1000000);
|
||||
|
||||
{
|
||||
SSIBus *spi;
|
||||
|
@@ -114,11 +114,11 @@ DeviceState *qdev_create(BusState *bus, const char *name)
|
||||
dev = qdev_try_create(bus, name);
|
||||
if (!dev) {
|
||||
if (bus) {
|
||||
error_report("Unknown device '%s' for bus '%s'\n", name,
|
||||
error_report("Unknown device '%s' for bus '%s'", name,
|
||||
object_get_typename(OBJECT(bus)));
|
||||
abort();
|
||||
} else {
|
||||
error_report("Unknown device '%s' for default sysbus\n", name);
|
||||
error_report("Unknown device '%s' for default sysbus", name);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
2
hw/qxl.c
2
hw/qxl.c
@@ -2036,7 +2036,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
|
||||
qxl->ssd.qxl.base.sif = &qxl_interface.base;
|
||||
qxl->ssd.qxl.id = qxl->id;
|
||||
if (qemu_spice_add_interface(&qxl->ssd.qxl.base) != 0) {
|
||||
error_report("qxl interface %d.%d not supported by spice-server\n",
|
||||
error_report("qxl interface %d.%d not supported by spice-server",
|
||||
SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR);
|
||||
return -1;
|
||||
}
|
||||
|
@@ -87,7 +87,7 @@ static void css_inject_io_interrupt(SubchDev *sch)
|
||||
css_build_subchannel_id(sch),
|
||||
sch->schid,
|
||||
sch->curr_status.pmcw.intparm,
|
||||
(0x80 >> isc) << 24);
|
||||
isc << 27);
|
||||
}
|
||||
|
||||
void css_conditional_io_interrupt(SubchDev *sch)
|
||||
@@ -111,7 +111,7 @@ void css_conditional_io_interrupt(SubchDev *sch)
|
||||
css_build_subchannel_id(sch),
|
||||
sch->schid,
|
||||
sch->curr_status.pmcw.intparm,
|
||||
(0x80 >> isc) << 24);
|
||||
isc << 27);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -153,7 +153,8 @@ static int s390_virtio_net_init(VirtIOS390Device *dev)
|
||||
{
|
||||
VirtIODevice *vdev;
|
||||
|
||||
vdev = virtio_net_init((DeviceState *)dev, &dev->nic, &dev->net);
|
||||
vdev = virtio_net_init((DeviceState *)dev, &dev->nic, &dev->net,
|
||||
dev->host_features);
|
||||
if (!vdev) {
|
||||
return -1;
|
||||
}
|
||||
|
@@ -44,12 +44,9 @@ typedef struct SCLPConsole {
|
||||
/* Return number of bytes that fit into iov buffer */
|
||||
static int chr_can_read(void *opaque)
|
||||
{
|
||||
int can_read;
|
||||
SCLPConsole *scon = opaque;
|
||||
|
||||
can_read = SIZE_BUFFER_VT220 - scon->iov_data_len;
|
||||
|
||||
return can_read;
|
||||
return scon->iov ? SIZE_BUFFER_VT220 - scon->iov_data_len : 0;
|
||||
}
|
||||
|
||||
/* Receive n bytes from character layer, save in iov buffer,
|
||||
|
@@ -555,7 +555,8 @@ static int virtio_ccw_net_init(VirtioCcwDevice *dev)
|
||||
{
|
||||
VirtIODevice *vdev;
|
||||
|
||||
vdev = virtio_net_init((DeviceState *)dev, &dev->nic, &dev->net);
|
||||
vdev = virtio_net_init((DeviceState *)dev, &dev->nic, &dev->net,
|
||||
dev->host_features[0]);
|
||||
if (!vdev) {
|
||||
return -1;
|
||||
}
|
||||
|
114
hw/vfio_pci.c
114
hw/vfio_pci.c
@@ -289,7 +289,7 @@ static void vfio_enable_intx_kvm(VFIODevice *vdev)
|
||||
|
||||
/* Get an eventfd for resample/unmask */
|
||||
if (event_notifier_init(&vdev->intx.unmask, 0)) {
|
||||
error_report("vfio: Error: event_notifier_init failed eoi\n");
|
||||
error_report("vfio: Error: event_notifier_init failed eoi");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ static void vfio_enable_intx_kvm(VFIODevice *vdev)
|
||||
irqfd.resamplefd = event_notifier_get_fd(&vdev->intx.unmask);
|
||||
|
||||
if (kvm_vm_ioctl(kvm_state, KVM_IRQFD, &irqfd)) {
|
||||
error_report("vfio: Error: Failed to setup resample irqfd: %m\n");
|
||||
error_report("vfio: Error: Failed to setup resample irqfd: %m");
|
||||
goto fail_irqfd;
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ static void vfio_enable_intx_kvm(VFIODevice *vdev)
|
||||
ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
||||
g_free(irq_set);
|
||||
if (ret) {
|
||||
error_report("vfio: Error: Failed to setup INTx unmask fd: %m\n");
|
||||
error_report("vfio: Error: Failed to setup INTx unmask fd: %m");
|
||||
goto fail_vfio;
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ static void vfio_disable_intx_kvm(VFIODevice *vdev)
|
||||
|
||||
/* Tell KVM to stop listening for an INTx irqfd */
|
||||
if (kvm_vm_ioctl(kvm_state, KVM_IRQFD, &irqfd)) {
|
||||
error_report("vfio: Error: Failed to disable INTx irqfd: %m\n");
|
||||
error_report("vfio: Error: Failed to disable INTx irqfd: %m");
|
||||
}
|
||||
|
||||
/* We only need to close the eventfd for VFIO to cleanup the kernel side */
|
||||
@@ -447,7 +447,7 @@ static int vfio_enable_intx(VFIODevice *vdev)
|
||||
|
||||
ret = event_notifier_init(&vdev->intx.interrupt, 0);
|
||||
if (ret) {
|
||||
error_report("vfio: Error: event_notifier_init failed\n");
|
||||
error_report("vfio: Error: event_notifier_init failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ static int vfio_enable_intx(VFIODevice *vdev)
|
||||
ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
||||
g_free(irq_set);
|
||||
if (ret) {
|
||||
error_report("vfio: Error: Failed to setup INTx fd: %m\n");
|
||||
error_report("vfio: Error: Failed to setup INTx fd: %m");
|
||||
qemu_set_fd_handler(*pfd, NULL, NULL, vdev);
|
||||
event_notifier_cleanup(&vdev->intx.interrupt);
|
||||
return -errno;
|
||||
@@ -526,7 +526,7 @@ static void vfio_msi_interrupt(void *opaque)
|
||||
} else if (vdev->interrupt == VFIO_INT_MSI) {
|
||||
msi_notify(&vdev->pdev, nr);
|
||||
} else {
|
||||
error_report("vfio: MSI interrupt receieved, but not enabled?\n");
|
||||
error_report("vfio: MSI interrupt receieved, but not enabled?");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,7 +580,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
||||
msix_vector_use(pdev, nr);
|
||||
|
||||
if (event_notifier_init(&vector->interrupt, 0)) {
|
||||
error_report("vfio: Error: event_notifier_init failed\n");
|
||||
error_report("vfio: Error: event_notifier_init failed");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -609,7 +609,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
||||
vdev->nr_vectors = nr + 1;
|
||||
ret = vfio_enable_vectors(vdev, true);
|
||||
if (ret) {
|
||||
error_report("vfio: failed to enable vectors, %d\n", ret);
|
||||
error_report("vfio: failed to enable vectors, %d", ret);
|
||||
}
|
||||
} else {
|
||||
int argsz;
|
||||
@@ -632,7 +632,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
||||
ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
||||
g_free(irq_set);
|
||||
if (ret) {
|
||||
error_report("vfio: failed to modify vector, %d\n", ret);
|
||||
error_report("vfio: failed to modify vector, %d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -721,7 +721,7 @@ static void vfio_enable_msix(VFIODevice *vdev)
|
||||
|
||||
if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
|
||||
vfio_msix_vector_release, NULL)) {
|
||||
error_report("vfio: msix_set_vector_notifiers failed\n");
|
||||
error_report("vfio: msix_set_vector_notifiers failed");
|
||||
}
|
||||
|
||||
DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
|
||||
@@ -746,7 +746,7 @@ retry:
|
||||
vector->use = true;
|
||||
|
||||
if (event_notifier_init(&vector->interrupt, 0)) {
|
||||
error_report("vfio: Error: event_notifier_init failed\n");
|
||||
error_report("vfio: Error: event_notifier_init failed");
|
||||
}
|
||||
|
||||
msg = msi_get_message(&vdev->pdev, i);
|
||||
@@ -767,10 +767,10 @@ retry:
|
||||
ret = vfio_enable_vectors(vdev, false);
|
||||
if (ret) {
|
||||
if (ret < 0) {
|
||||
error_report("vfio: Error: Failed to setup MSI fds: %m\n");
|
||||
error_report("vfio: Error: Failed to setup MSI fds: %m");
|
||||
} else if (ret != vdev->nr_vectors) {
|
||||
error_report("vfio: Error: Failed to enable %d "
|
||||
"MSI vectors, retry with %d\n", vdev->nr_vectors, ret);
|
||||
"MSI vectors, retry with %d", vdev->nr_vectors, ret);
|
||||
}
|
||||
|
||||
for (i = 0; i < vdev->nr_vectors; i++) {
|
||||
@@ -891,7 +891,7 @@ static void vfio_bar_write(void *opaque, hwaddr addr,
|
||||
}
|
||||
|
||||
if (pwrite(bar->fd, &buf, size, bar->fd_offset + addr) != size) {
|
||||
error_report("%s(,0x%"HWADDR_PRIx", 0x%"PRIx64", %d) failed: %m\n",
|
||||
error_report("%s(,0x%"HWADDR_PRIx", 0x%"PRIx64", %d) failed: %m",
|
||||
__func__, addr, data, size);
|
||||
}
|
||||
|
||||
@@ -922,7 +922,7 @@ static uint64_t vfio_bar_read(void *opaque,
|
||||
uint64_t data = 0;
|
||||
|
||||
if (pread(bar->fd, &buf, size, bar->fd_offset + addr) != size) {
|
||||
error_report("%s(,0x%"HWADDR_PRIx", %d) failed: %m\n",
|
||||
error_report("%s(,0x%"HWADDR_PRIx", %d) failed: %m",
|
||||
__func__, addr, size);
|
||||
return (uint64_t)-1;
|
||||
}
|
||||
@@ -979,7 +979,7 @@ static uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
|
||||
val = pci_default_read_config(pdev, addr, len);
|
||||
} else {
|
||||
if (pread(vdev->fd, &val, len, vdev->config_offset + addr) != len) {
|
||||
error_report("%s(%04x:%02x:%02x.%x, 0x%x, 0x%x) failed: %m\n",
|
||||
error_report("%s(%04x:%02x:%02x.%x, 0x%x, 0x%x) failed: %m",
|
||||
__func__, vdev->host.domain, vdev->host.bus,
|
||||
vdev->host.slot, vdev->host.function, addr, len);
|
||||
return -errno;
|
||||
@@ -1021,7 +1021,7 @@ static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr,
|
||||
|
||||
/* Write everything to VFIO, let it filter out what we can't write */
|
||||
if (pwrite(vdev->fd, &val_le, len, vdev->config_offset + addr) != len) {
|
||||
error_report("%s(%04x:%02x:%02x.%x, 0x%x, 0x%x, 0x%x) failed: %m\n",
|
||||
error_report("%s(%04x:%02x:%02x.%x, 0x%x, 0x%x, 0x%x) failed: %m",
|
||||
__func__, vdev->host.domain, vdev->host.bus,
|
||||
vdev->host.slot, vdev->host.function, addr, val, len);
|
||||
}
|
||||
@@ -1138,7 +1138,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
|
||||
|
||||
if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
|
||||
(section->offset_within_region & ~TARGET_PAGE_MASK))) {
|
||||
error_report("%s received unaligned region\n", __func__);
|
||||
error_report("%s received unaligned region", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1160,7 +1160,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
|
||||
ret = vfio_dma_map(container, iova, end - iova, vaddr, section->readonly);
|
||||
if (ret) {
|
||||
error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
|
||||
"0x%"HWADDR_PRIx", %p) = %d (%m)\n",
|
||||
"0x%"HWADDR_PRIx", %p) = %d (%m)",
|
||||
container, iova, end - iova, vaddr, ret);
|
||||
}
|
||||
}
|
||||
@@ -1182,7 +1182,7 @@ static void vfio_listener_region_del(MemoryListener *listener,
|
||||
|
||||
if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
|
||||
(section->offset_within_region & ~TARGET_PAGE_MASK))) {
|
||||
error_report("%s received unaligned region\n", __func__);
|
||||
error_report("%s received unaligned region", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1200,7 +1200,7 @@ static void vfio_listener_region_del(MemoryListener *listener,
|
||||
ret = vfio_dma_unmap(container, iova, end - iova);
|
||||
if (ret) {
|
||||
error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", "
|
||||
"0x%"HWADDR_PRIx") = %d (%m)\n",
|
||||
"0x%"HWADDR_PRIx") = %d (%m)",
|
||||
container, iova, end - iova, ret);
|
||||
}
|
||||
}
|
||||
@@ -1257,7 +1257,7 @@ static int vfio_setup_msi(VFIODevice *vdev, int pos)
|
||||
if (ret == -ENOTSUP) {
|
||||
return 0;
|
||||
}
|
||||
error_report("vfio: msi_init failed\n");
|
||||
error_report("vfio: msi_init failed");
|
||||
return ret;
|
||||
}
|
||||
vdev->msi_cap_size = 0xa + (msi_maskbit ? 0xa : 0) + (msi_64bit ? 0x4 : 0);
|
||||
@@ -1332,7 +1332,7 @@ static int vfio_setup_msix(VFIODevice *vdev, int pos)
|
||||
if (ret == -ENOTSUP) {
|
||||
return 0;
|
||||
}
|
||||
error_report("vfio: msix_init failed\n");
|
||||
error_report("vfio: msix_init failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1448,7 +1448,7 @@ static void vfio_map_bar(VFIODevice *vdev, int nr)
|
||||
ret = pread(vdev->fd, &pci_bar, sizeof(pci_bar),
|
||||
vdev->config_offset + PCI_BASE_ADDRESS_0 + (4 * nr));
|
||||
if (ret != sizeof(pci_bar)) {
|
||||
error_report("vfio: Failed to read BAR %d (%m)\n", nr);
|
||||
error_report("vfio: Failed to read BAR %d (%m)", nr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1471,7 +1471,7 @@ static void vfio_map_bar(VFIODevice *vdev, int nr)
|
||||
strncat(name, " mmap", sizeof(name) - strlen(name) - 1);
|
||||
if (vfio_mmap_bar(bar, &bar->mem,
|
||||
&bar->mmap_mem, &bar->mmap, size, 0, name)) {
|
||||
error_report("%s unsupported. Performance may be slow\n", name);
|
||||
error_report("%s unsupported. Performance may be slow", name);
|
||||
}
|
||||
|
||||
if (vdev->msix && vdev->msix->table_bar == nr) {
|
||||
@@ -1485,7 +1485,7 @@ static void vfio_map_bar(VFIODevice *vdev, int nr)
|
||||
/* VFIOMSIXInfo contains another MemoryRegion for this mapping */
|
||||
if (vfio_mmap_bar(bar, &bar->mem, &vdev->msix->mmap_mem,
|
||||
&vdev->msix->mmap, size, start, name)) {
|
||||
error_report("%s unsupported. Performance may be slow\n", name);
|
||||
error_report("%s unsupported. Performance may be slow", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1572,7 +1572,7 @@ static int vfio_add_std_cap(VFIODevice *vdev, uint8_t pos)
|
||||
|
||||
if (ret < 0) {
|
||||
error_report("vfio: %04x:%02x:%02x.%x Error adding PCI capability "
|
||||
"0x%x[0x%x]@0x%x: %d\n", vdev->host.domain,
|
||||
"0x%x[0x%x]@0x%x: %d", vdev->host.domain,
|
||||
vdev->host.bus, vdev->host.slot, vdev->host.function,
|
||||
cap_id, size, pos, ret);
|
||||
return ret;
|
||||
@@ -1627,7 +1627,7 @@ static int vfio_load_rom(VFIODevice *vdev)
|
||||
if (errno == EINTR || errno == EAGAIN) {
|
||||
continue;
|
||||
}
|
||||
error_report("vfio: Error reading device ROM: %m\n");
|
||||
error_report("vfio: Error reading device ROM: %m");
|
||||
memory_region_destroy(&vdev->pdev.rom);
|
||||
return -errno;
|
||||
}
|
||||
@@ -1657,14 +1657,14 @@ static int vfio_connect_container(VFIOGroup *group)
|
||||
|
||||
fd = qemu_open("/dev/vfio/vfio", O_RDWR);
|
||||
if (fd < 0) {
|
||||
error_report("vfio: failed to open /dev/vfio/vfio: %m\n");
|
||||
error_report("vfio: failed to open /dev/vfio/vfio: %m");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, VFIO_GET_API_VERSION);
|
||||
if (ret != VFIO_API_VERSION) {
|
||||
error_report("vfio: supported vfio version: %d, "
|
||||
"reported version: %d\n", VFIO_API_VERSION, ret);
|
||||
"reported version: %d", VFIO_API_VERSION, ret);
|
||||
close(fd);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1675,7 +1675,7 @@ static int vfio_connect_container(VFIOGroup *group)
|
||||
if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU)) {
|
||||
ret = ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd);
|
||||
if (ret) {
|
||||
error_report("vfio: failed to set group container: %m\n");
|
||||
error_report("vfio: failed to set group container: %m");
|
||||
g_free(container);
|
||||
close(fd);
|
||||
return -errno;
|
||||
@@ -1683,7 +1683,7 @@ static int vfio_connect_container(VFIOGroup *group)
|
||||
|
||||
ret = ioctl(fd, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
|
||||
if (ret) {
|
||||
error_report("vfio: failed to set iommu for container: %m\n");
|
||||
error_report("vfio: failed to set iommu for container: %m");
|
||||
g_free(container);
|
||||
close(fd);
|
||||
return -errno;
|
||||
@@ -1694,7 +1694,7 @@ static int vfio_connect_container(VFIOGroup *group)
|
||||
|
||||
memory_listener_register(&container->iommu_data.listener, &address_space_memory);
|
||||
} else {
|
||||
error_report("vfio: No available IOMMU models\n");
|
||||
error_report("vfio: No available IOMMU models");
|
||||
g_free(container);
|
||||
close(fd);
|
||||
return -EINVAL;
|
||||
@@ -1714,7 +1714,7 @@ static void vfio_disconnect_container(VFIOGroup *group)
|
||||
VFIOContainer *container = group->container;
|
||||
|
||||
if (ioctl(group->fd, VFIO_GROUP_UNSET_CONTAINER, &container->fd)) {
|
||||
error_report("vfio: error disconnecting group %d from container\n",
|
||||
error_report("vfio: error disconnecting group %d from container",
|
||||
group->groupid);
|
||||
}
|
||||
|
||||
@@ -1749,13 +1749,13 @@ static VFIOGroup *vfio_get_group(int groupid)
|
||||
snprintf(path, sizeof(path), "/dev/vfio/%d", groupid);
|
||||
group->fd = qemu_open(path, O_RDWR);
|
||||
if (group->fd < 0) {
|
||||
error_report("vfio: error opening %s: %m\n", path);
|
||||
error_report("vfio: error opening %s: %m", path);
|
||||
g_free(group);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ioctl(group->fd, VFIO_GROUP_GET_STATUS, &status)) {
|
||||
error_report("vfio: error getting group status: %m\n");
|
||||
error_report("vfio: error getting group status: %m");
|
||||
close(group->fd);
|
||||
g_free(group);
|
||||
return NULL;
|
||||
@@ -1764,7 +1764,7 @@ static VFIOGroup *vfio_get_group(int groupid)
|
||||
if (!(status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
|
||||
error_report("vfio: error, group %d is not viable, please ensure "
|
||||
"all devices within the iommu_group are bound to their "
|
||||
"vfio bus driver.\n", groupid);
|
||||
"vfio bus driver.", groupid);
|
||||
close(group->fd);
|
||||
g_free(group);
|
||||
return NULL;
|
||||
@@ -1774,7 +1774,7 @@ static VFIOGroup *vfio_get_group(int groupid)
|
||||
QLIST_INIT(&group->device_list);
|
||||
|
||||
if (vfio_connect_container(group)) {
|
||||
error_report("vfio: failed to setup container for group %d\n", groupid);
|
||||
error_report("vfio: failed to setup container for group %d", groupid);
|
||||
close(group->fd);
|
||||
g_free(group);
|
||||
return NULL;
|
||||
@@ -1806,9 +1806,9 @@ static int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vdev)
|
||||
|
||||
ret = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, name);
|
||||
if (ret < 0) {
|
||||
error_report("vfio: error getting device %s from group %d: %m\n",
|
||||
error_report("vfio: error getting device %s from group %d: %m",
|
||||
name, group->groupid);
|
||||
error_report("Verify all devices in group %d are bound to vfio-pci "
|
||||
error_printf("Verify all devices in group %d are bound to vfio-pci "
|
||||
"or pci-stub and not already in use\n", group->groupid);
|
||||
return ret;
|
||||
}
|
||||
@@ -1820,7 +1820,7 @@ static int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vdev)
|
||||
/* Sanity check device */
|
||||
ret = ioctl(vdev->fd, VFIO_DEVICE_GET_INFO, &dev_info);
|
||||
if (ret) {
|
||||
error_report("vfio: error getting device info: %m\n");
|
||||
error_report("vfio: error getting device info: %m");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -1828,23 +1828,23 @@ static int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vdev)
|
||||
dev_info.flags, dev_info.num_regions, dev_info.num_irqs);
|
||||
|
||||
if (!(dev_info.flags & VFIO_DEVICE_FLAGS_PCI)) {
|
||||
error_report("vfio: Um, this isn't a PCI device\n");
|
||||
error_report("vfio: Um, this isn't a PCI device");
|
||||
goto error;
|
||||
}
|
||||
|
||||
vdev->reset_works = !!(dev_info.flags & VFIO_DEVICE_FLAGS_RESET);
|
||||
if (!vdev->reset_works) {
|
||||
error_report("Warning, device %s does not support reset\n", name);
|
||||
error_report("Warning, device %s does not support reset", name);
|
||||
}
|
||||
|
||||
if (dev_info.num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {
|
||||
error_report("vfio: unexpected number of io regions %u\n",
|
||||
error_report("vfio: unexpected number of io regions %u",
|
||||
dev_info.num_regions);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dev_info.num_irqs < VFIO_PCI_MSIX_IRQ_INDEX + 1) {
|
||||
error_report("vfio: unexpected number of irqs %u\n", dev_info.num_irqs);
|
||||
error_report("vfio: unexpected number of irqs %u", dev_info.num_irqs);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -1853,7 +1853,7 @@ static int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vdev)
|
||||
|
||||
ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, ®_info);
|
||||
if (ret) {
|
||||
error_report("vfio: Error getting region %d info: %m\n", i);
|
||||
error_report("vfio: Error getting region %d info: %m", i);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -1873,7 +1873,7 @@ static int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vdev)
|
||||
|
||||
ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, ®_info);
|
||||
if (ret) {
|
||||
error_report("vfio: Error getting ROM info: %m\n");
|
||||
error_report("vfio: Error getting ROM info: %m");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -1889,7 +1889,7 @@ static int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vdev)
|
||||
|
||||
ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, ®_info);
|
||||
if (ret) {
|
||||
error_report("vfio: Error getting config info: %m\n");
|
||||
error_report("vfio: Error getting config info: %m");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -1941,7 +1941,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
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\n", path);
|
||||
error_report("vfio: error: no such host device: %s", path);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
@@ -1949,7 +1949,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
|
||||
len = readlink(path, iommu_group_path, PATH_MAX);
|
||||
if (len <= 0) {
|
||||
error_report("vfio: error no iommu_group for device\n");
|
||||
error_report("vfio: error no iommu_group for device");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
@@ -1957,7 +1957,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
group_name = basename(iommu_group_path);
|
||||
|
||||
if (sscanf(group_name, "%d", &groupid) != 1) {
|
||||
error_report("vfio: error reading %s: %m\n", path);
|
||||
error_report("vfio: error reading %s: %m", path);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
@@ -1966,7 +1966,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
|
||||
group = vfio_get_group(groupid);
|
||||
if (!group) {
|
||||
error_report("vfio: failed to get group %d\n", groupid);
|
||||
error_report("vfio: failed to get group %d", groupid);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
@@ -1980,7 +1980,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
pvdev->host.slot == vdev->host.slot &&
|
||||
pvdev->host.function == vdev->host.function) {
|
||||
|
||||
error_report("vfio: error: device %s is already attached\n", path);
|
||||
error_report("vfio: error: device %s is already attached", path);
|
||||
vfio_put_group(group);
|
||||
return -EBUSY;
|
||||
}
|
||||
@@ -1988,7 +1988,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
|
||||
ret = vfio_get_device(group, path, vdev);
|
||||
if (ret) {
|
||||
error_report("vfio: failed to get device %s\n", path);
|
||||
error_report("vfio: failed to get device %s", path);
|
||||
vfio_put_group(group);
|
||||
return ret;
|
||||
}
|
||||
@@ -1999,7 +1999,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
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\n");
|
||||
error_report("vfio: Failed to read device config space");
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
@@ -2086,7 +2086,7 @@ static void vfio_pci_reset(DeviceState *dev)
|
||||
if (vdev->reset_works) {
|
||||
if (ioctl(vdev->fd, VFIO_DEVICE_RESET)) {
|
||||
error_report("vfio: Error unable to reset physical device "
|
||||
"(%04x:%02x:%02x.%x): %m\n", vdev->host.domain,
|
||||
"(%04x:%02x:%02x.%x): %m", vdev->host.domain,
|
||||
vdev->host.bus, vdev->host.slot, vdev->host.function);
|
||||
}
|
||||
}
|
||||
|
@@ -214,7 +214,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
|
||||
int r, i = 0;
|
||||
|
||||
if (!dev->binding->set_guest_notifiers) {
|
||||
error_report("binding does not support guest notifiers\n");
|
||||
error_report("binding does not support guest notifiers");
|
||||
r = -ENOSYS;
|
||||
goto err;
|
||||
}
|
||||
@@ -231,7 +231,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
|
||||
total_queues * 2,
|
||||
true);
|
||||
if (r < 0) {
|
||||
error_report("Error binding guest notifier: %d\n", -r);
|
||||
error_report("Error binding guest notifier: %d", -r);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@@ -73,8 +73,31 @@ typedef struct VirtIONet
|
||||
int multiqueue;
|
||||
uint16_t max_queues;
|
||||
uint16_t curr_queues;
|
||||
size_t config_size;
|
||||
} VirtIONet;
|
||||
|
||||
/*
|
||||
* Calculate the number of bytes up to and including the given 'field' of
|
||||
* 'container'.
|
||||
*/
|
||||
#define endof(container, field) \
|
||||
(offsetof(container, field) + sizeof(((container *)0)->field))
|
||||
|
||||
typedef struct VirtIOFeature {
|
||||
uint32_t flags;
|
||||
size_t end;
|
||||
} VirtIOFeature;
|
||||
|
||||
static VirtIOFeature feature_sizes[] = {
|
||||
{.flags = 1 << VIRTIO_NET_F_MAC,
|
||||
.end = endof(struct virtio_net_config, mac)},
|
||||
{.flags = 1 << VIRTIO_NET_F_STATUS,
|
||||
.end = endof(struct virtio_net_config, status)},
|
||||
{.flags = 1 << VIRTIO_NET_F_MQ,
|
||||
.end = endof(struct virtio_net_config, max_virtqueue_pairs)},
|
||||
{}
|
||||
};
|
||||
|
||||
static VirtIONetQueue *virtio_net_get_subqueue(NetClientState *nc)
|
||||
{
|
||||
VirtIONet *n = qemu_get_nic_opaque(nc);
|
||||
@@ -104,15 +127,15 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
|
||||
stw_p(&netcfg.status, n->status);
|
||||
stw_p(&netcfg.max_virtqueue_pairs, n->max_queues);
|
||||
memcpy(netcfg.mac, n->mac, ETH_ALEN);
|
||||
memcpy(config, &netcfg, sizeof(netcfg));
|
||||
memcpy(config, &netcfg, n->config_size);
|
||||
}
|
||||
|
||||
static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
|
||||
{
|
||||
VirtIONet *n = to_virtio_net(vdev);
|
||||
struct virtio_net_config netcfg;
|
||||
struct virtio_net_config netcfg = {};
|
||||
|
||||
memcpy(&netcfg, config, sizeof(netcfg));
|
||||
memcpy(&netcfg, config, n->config_size);
|
||||
|
||||
if (!(n->vdev.guest_features >> VIRTIO_NET_F_CTRL_MAC_ADDR & 1) &&
|
||||
memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
|
||||
@@ -1279,15 +1302,21 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
|
||||
}
|
||||
|
||||
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
|
||||
virtio_net_conf *net)
|
||||
virtio_net_conf *net, uint32_t host_features)
|
||||
{
|
||||
VirtIONet *n;
|
||||
int i;
|
||||
int i, config_size = 0;
|
||||
|
||||
for (i = 0; feature_sizes[i].flags != 0; i++) {
|
||||
if (host_features & feature_sizes[i].flags) {
|
||||
config_size = MAX(feature_sizes[i].end, config_size);
|
||||
}
|
||||
}
|
||||
|
||||
n = (VirtIONet *)virtio_common_init("virtio-net", VIRTIO_ID_NET,
|
||||
sizeof(struct virtio_net_config),
|
||||
sizeof(VirtIONet));
|
||||
config_size, sizeof(VirtIONet));
|
||||
|
||||
n->config_size = config_size;
|
||||
n->vdev.get_config = virtio_net_get_config;
|
||||
n->vdev.set_config = virtio_net_set_config;
|
||||
n->vdev.get_features = virtio_net_get_features;
|
||||
|
@@ -191,6 +191,6 @@ struct virtio_net_ctrl_mq {
|
||||
DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
|
||||
DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true), \
|
||||
DEFINE_PROP_BIT("ctrl_mac_addr", _state, _field, VIRTIO_NET_F_CTRL_MAC_ADDR, true), \
|
||||
DEFINE_PROP_BIT("mq", _state, _field, VIRTIO_NET_F_MQ, true)
|
||||
DEFINE_PROP_BIT("mq", _state, _field, VIRTIO_NET_F_MQ, false)
|
||||
|
||||
#endif
|
||||
|
@@ -997,7 +997,8 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
|
||||
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
|
||||
VirtIODevice *vdev;
|
||||
|
||||
vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net);
|
||||
vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net,
|
||||
proxy->host_features);
|
||||
|
||||
vdev->nvectors = proxy->nvectors;
|
||||
virtio_init_pci(proxy, vdev);
|
||||
|
@@ -243,7 +243,8 @@ typedef struct VirtIOBlkConf VirtIOBlkConf;
|
||||
VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk);
|
||||
struct virtio_net_conf;
|
||||
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
|
||||
struct virtio_net_conf *net);
|
||||
struct virtio_net_conf *net,
|
||||
uint32_t host_features);
|
||||
typedef struct virtio_serial_conf virtio_serial_conf;
|
||||
VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *serial);
|
||||
VirtIODevice *virtio_balloon_init(DeviceState *dev);
|
||||
|
18
hw/xilinx.h
18
hw/xilinx.h
@@ -53,17 +53,12 @@ xilinx_ethlite_create(NICInfo *nd, hwaddr base, qemu_irq irq,
|
||||
return dev;
|
||||
}
|
||||
|
||||
static inline DeviceState *
|
||||
xilinx_axiethernet_create(NICInfo *nd, StreamSlave *peer,
|
||||
hwaddr base, qemu_irq irq,
|
||||
int txmem, int rxmem)
|
||||
static inline void
|
||||
xilinx_axiethernet_init(DeviceState *dev, NICInfo *nd, StreamSlave *peer,
|
||||
hwaddr base, qemu_irq irq, int txmem, int rxmem)
|
||||
{
|
||||
DeviceState *dev;
|
||||
Error *errp = NULL;
|
||||
|
||||
qemu_check_nic_model(nd, "xlnx.axi-ethernet");
|
||||
|
||||
dev = qdev_create(NULL, "xlnx.axi-ethernet");
|
||||
qdev_set_nic_properties(dev, nd);
|
||||
qdev_prop_set_uint32(dev, "rxmem", rxmem);
|
||||
qdev_prop_set_uint32(dev, "txmem", txmem);
|
||||
@@ -73,14 +68,11 @@ xilinx_axiethernet_create(NICInfo *nd, StreamSlave *peer,
|
||||
qdev_init_nofail(dev);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static inline void
|
||||
xilinx_axiethernetdma_init(DeviceState *dev, StreamSlave *peer,
|
||||
hwaddr base, qemu_irq irq,
|
||||
qemu_irq irq2, int freqhz)
|
||||
xilinx_axidma_init(DeviceState *dev, StreamSlave *peer, hwaddr base,
|
||||
qemu_irq irq, qemu_irq irq2, int freqhz)
|
||||
{
|
||||
Error *errp = NULL;
|
||||
|
||||
|
@@ -168,7 +168,7 @@ static void zynq_init(QEMUMachineInitArgs *args)
|
||||
zynq_init_spi_flashes(0xE000D000, pic[51-IRQ_OFFSET], true);
|
||||
|
||||
sysbus_create_simple("xlnx,ps7-usb", 0xE0002000, pic[53-IRQ_OFFSET]);
|
||||
sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[75-IRQ_OFFSET]);
|
||||
sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[76-IRQ_OFFSET]);
|
||||
|
||||
sysbus_create_simple("cadence_uart", 0xE0000000, pic[59-IRQ_OFFSET]);
|
||||
sysbus_create_simple("cadence_uart", 0xE0001000, pic[82-IRQ_OFFSET]);
|
||||
|
@@ -81,6 +81,7 @@ QEMUFile *qemu_popen(FILE *popen_file, const char *mode);
|
||||
QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
|
||||
int qemu_get_fd(QEMUFile *f);
|
||||
int qemu_fclose(QEMUFile *f);
|
||||
int64_t qemu_ftell(QEMUFile *f);
|
||||
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
|
||||
void qemu_put_byte(QEMUFile *f, int v);
|
||||
|
||||
|
10
migration.c
10
migration.c
@@ -85,7 +85,7 @@ void qemu_start_incoming_migration(const char *uri, Error **errp)
|
||||
fd_start_incoming_migration(p, errp);
|
||||
#endif
|
||||
else {
|
||||
error_setg(errp, "unknown migration protocol: %s\n", uri);
|
||||
error_setg(errp, "unknown migration protocol: %s", uri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,6 @@ static void process_incoming_migration_co(void *opaque)
|
||||
int ret;
|
||||
|
||||
ret = qemu_loadvm_state(f);
|
||||
qemu_set_fd_handler(qemu_get_fd(f), NULL, NULL, NULL);
|
||||
qemu_fclose(f);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "load of migration failed\n");
|
||||
@@ -115,12 +114,6 @@ static void process_incoming_migration_co(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
static void enter_migration_coroutine(void *opaque)
|
||||
{
|
||||
Coroutine *co = opaque;
|
||||
qemu_coroutine_enter(co, NULL);
|
||||
}
|
||||
|
||||
void process_incoming_migration(QEMUFile *f)
|
||||
{
|
||||
Coroutine *co = qemu_coroutine_create(process_incoming_migration_co);
|
||||
@@ -128,7 +121,6 @@ void process_incoming_migration(QEMUFile *f)
|
||||
|
||||
assert(fd != -1);
|
||||
socket_set_nonblock(fd);
|
||||
qemu_set_fd_handler(fd, enter_migration_coroutine, NULL, co);
|
||||
qemu_coroutine_enter(co, f);
|
||||
}
|
||||
|
||||
|
@@ -287,7 +287,9 @@ static void qemu_cleanup_net_client(NetClientState *nc)
|
||||
{
|
||||
QTAILQ_REMOVE(&net_clients, nc, next);
|
||||
|
||||
nc->info->cleanup(nc);
|
||||
if (nc->info->cleanup) {
|
||||
nc->info->cleanup(nc);
|
||||
}
|
||||
}
|
||||
|
||||
static void qemu_free_net_client(NetClientState *nc)
|
||||
@@ -351,7 +353,7 @@ void qemu_del_net_client(NetClientState *nc)
|
||||
|
||||
void qemu_del_nic(NICState *nic)
|
||||
{
|
||||
int i, queues = nic->conf->queues;
|
||||
int i, queues = MAX(nic->conf->queues, 1);
|
||||
|
||||
/* If this is a peer NIC and peer has already been deleted, free it now. */
|
||||
if (nic->peer_deleted) {
|
||||
|
@@ -3095,7 +3095,7 @@
|
||||
'out' : 'str' } }
|
||||
|
||||
##
|
||||
# @ChardevPort:
|
||||
# @ChardevHostdev:
|
||||
#
|
||||
# Configuration info for device chardevs.
|
||||
#
|
||||
@@ -3105,11 +3105,7 @@
|
||||
#
|
||||
# Since: 1.4
|
||||
##
|
||||
{ 'enum': 'ChardevPortKind', 'data': [ 'serial',
|
||||
'parallel' ] }
|
||||
|
||||
{ 'type': 'ChardevPort', 'data': { 'device' : 'str',
|
||||
'type' : 'ChardevPortKind'} }
|
||||
{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } }
|
||||
|
||||
##
|
||||
# @ChardevSocket:
|
||||
@@ -3142,7 +3138,8 @@
|
||||
{ 'type': 'ChardevDummy', 'data': { } }
|
||||
|
||||
{ 'union': 'ChardevBackend', 'data': { 'file' : 'ChardevFile',
|
||||
'port' : 'ChardevPort',
|
||||
'serial' : 'ChardevHostdev',
|
||||
'parallel': 'ChardevHostdev',
|
||||
'socket' : 'ChardevSocket',
|
||||
'pty' : 'ChardevDummy',
|
||||
'null' : 'ChardevDummy' } }
|
||||
@@ -3152,6 +3149,9 @@
|
||||
#
|
||||
# Return info about the chardev backend just created.
|
||||
#
|
||||
# @pty: #optional name of the slave pseudoterminal device, present if
|
||||
# and only if a chardev of type 'pty' was created
|
||||
#
|
||||
# Since: 1.4
|
||||
##
|
||||
{ 'type' : 'ChardevReturn', 'data': { '*pty' : 'str' } }
|
||||
@@ -3159,12 +3159,12 @@
|
||||
##
|
||||
# @chardev-add:
|
||||
#
|
||||
# Add a file chardev
|
||||
# Add a character device backend
|
||||
#
|
||||
# @id: the chardev's ID, must be unique
|
||||
# @backend: backend type and parameters
|
||||
#
|
||||
# Returns: chardev info.
|
||||
# Returns: ChardevReturn.
|
||||
#
|
||||
# Since: 1.4
|
||||
##
|
||||
@@ -3175,7 +3175,7 @@
|
||||
##
|
||||
# @chardev-remove:
|
||||
#
|
||||
# Remove a chardev
|
||||
# Remove a character device backend
|
||||
#
|
||||
# @id: the chardev's ID, must exist and not be in use
|
||||
#
|
||||
|
90
qemu-char.c
90
qemu-char.c
@@ -3021,12 +3021,12 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
|
||||
int i;
|
||||
|
||||
if (qemu_opts_id(opts) == NULL) {
|
||||
error_setg(errp, "chardev: no id specified\n");
|
||||
error_setg(errp, "chardev: no id specified");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (qemu_opt_get(opts, "backend") == NULL) {
|
||||
error_setg(errp, "chardev: \"%s\" missing backend\n",
|
||||
error_setg(errp, "chardev: \"%s\" missing backend",
|
||||
qemu_opts_id(opts));
|
||||
goto err;
|
||||
}
|
||||
@@ -3035,14 +3035,14 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(backend_table)) {
|
||||
error_setg(errp, "chardev: backend \"%s\" not found\n",
|
||||
error_setg(errp, "chardev: backend \"%s\" not found",
|
||||
qemu_opt_get(opts, "backend"));
|
||||
goto err;
|
||||
}
|
||||
|
||||
chr = backend_table[i].open(opts);
|
||||
if (!chr) {
|
||||
error_setg(errp, "chardev: opening backend \"%s\" failed\n",
|
||||
error_setg(errp, "chardev: opening backend \"%s\" failed",
|
||||
qemu_opt_get(opts, "backend"));
|
||||
goto err;
|
||||
}
|
||||
@@ -3269,15 +3269,17 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
|
||||
return qemu_chr_open_win_file(out);
|
||||
}
|
||||
|
||||
static CharDriverState *qmp_chardev_open_port(ChardevPort *port, Error **errp)
|
||||
static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
|
||||
Error **errp)
|
||||
{
|
||||
switch (port->type) {
|
||||
case CHARDEV_PORT_KIND_SERIAL:
|
||||
return qemu_chr_open_win_path(port->device);
|
||||
default:
|
||||
error_setg(errp, "unknown chardev port (%d)", port->type);
|
||||
return NULL;
|
||||
}
|
||||
return qemu_chr_open_win_path(serial->device);
|
||||
}
|
||||
|
||||
static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
|
||||
Error **errp)
|
||||
{
|
||||
error_setg(errp, "character device backend type 'parallel' not supported");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else /* WIN32 */
|
||||
@@ -3316,38 +3318,39 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
|
||||
return qemu_chr_open_fd(in, out);
|
||||
}
|
||||
|
||||
static CharDriverState *qmp_chardev_open_port(ChardevPort *port, Error **errp)
|
||||
static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
|
||||
Error **errp)
|
||||
{
|
||||
switch (port->type) {
|
||||
#ifdef HAVE_CHARDEV_TTY
|
||||
case CHARDEV_PORT_KIND_SERIAL:
|
||||
{
|
||||
int flags, fd;
|
||||
flags = O_RDWR;
|
||||
fd = qmp_chardev_open_file_source(port->device, flags, errp);
|
||||
if (error_is_set(errp)) {
|
||||
return NULL;
|
||||
}
|
||||
socket_set_nonblock(fd);
|
||||
return qemu_chr_open_tty_fd(fd);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CHARDEV_PARPORT
|
||||
case CHARDEV_PORT_KIND_PARALLEL:
|
||||
{
|
||||
int flags, fd;
|
||||
flags = O_RDWR;
|
||||
fd = qmp_chardev_open_file_source(port->device, flags, errp);
|
||||
if (error_is_set(errp)) {
|
||||
return NULL;
|
||||
}
|
||||
return qemu_chr_open_pp_fd(fd);
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
error_setg(errp, "unknown chardev port (%d)", port->type);
|
||||
int fd;
|
||||
|
||||
fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
|
||||
if (error_is_set(errp)) {
|
||||
return NULL;
|
||||
}
|
||||
socket_set_nonblock(fd);
|
||||
return qemu_chr_open_tty_fd(fd);
|
||||
#else
|
||||
error_setg(errp, "character device backend type 'serial' not supported");
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
|
||||
Error **errp)
|
||||
{
|
||||
#ifdef HAVE_CHARDEV_PARPORT
|
||||
int fd;
|
||||
|
||||
fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
|
||||
if (error_is_set(errp)) {
|
||||
return NULL;
|
||||
}
|
||||
return qemu_chr_open_pp_fd(fd);
|
||||
#else
|
||||
error_setg(errp, "character device backend type 'parallel' not supported");
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
@@ -3391,8 +3394,11 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
|
||||
case CHARDEV_BACKEND_KIND_FILE:
|
||||
chr = qmp_chardev_open_file(backend->file, errp);
|
||||
break;
|
||||
case CHARDEV_BACKEND_KIND_PORT:
|
||||
chr = qmp_chardev_open_port(backend->port, errp);
|
||||
case CHARDEV_BACKEND_KIND_SERIAL:
|
||||
chr = qmp_chardev_open_serial(backend->serial, errp);
|
||||
break;
|
||||
case CHARDEV_BACKEND_KIND_PARALLEL:
|
||||
chr = qmp_chardev_open_parallel(backend->parallel, errp);
|
||||
break;
|
||||
case CHARDEV_BACKEND_KIND_SOCKET:
|
||||
chr = qmp_chardev_open_socket(backend->socket, errp);
|
||||
|
@@ -29,7 +29,12 @@ Export QEMU disk image using NBD protocol.
|
||||
@item -s, --snapshot
|
||||
use snapshot file
|
||||
@item -n, --nocache
|
||||
disable host cache
|
||||
@itemx --cache=@var{cache}
|
||||
set cache mode to be used with the file. See the documentation of
|
||||
the emulator's @code{-drive cache=...} option for allowed values.
|
||||
@item --aio=@var{aio}
|
||||
choose asynchronous I/O mode between @samp{threads} (the default)
|
||||
and @samp{native} (Linux only).
|
||||
@item -c, --connect=@var{dev}
|
||||
connect @var{filename} to NBD device @var{dev}
|
||||
@item -d, --disconnect
|
||||
|
@@ -1956,7 +1956,7 @@ Connect to a local BrlAPI server. @option{braille} does not take any options.
|
||||
@item -chardev tty ,id=@var{id} ,path=@var{path}
|
||||
|
||||
@option{tty} is only available on Linux, Sun, FreeBSD, NetBSD, OpenBSD and
|
||||
DragonFlyBSD hosts. It is an alias for -serial.
|
||||
DragonFlyBSD hosts. It is an alias for @option{serial}.
|
||||
|
||||
@option{path} specifies the path to the tty. @option{path} is required.
|
||||
|
||||
|
8
qtest.c
8
qtest.c
@@ -282,8 +282,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
|
||||
uint8_t *data;
|
||||
|
||||
g_assert(words[1] && words[2]);
|
||||
addr = strtoul(words[1], NULL, 0);
|
||||
len = strtoul(words[2], NULL, 0);
|
||||
addr = strtoull(words[1], NULL, 0);
|
||||
len = strtoull(words[2], NULL, 0);
|
||||
|
||||
data = g_malloc(len);
|
||||
cpu_physical_memory_read(addr, data, len);
|
||||
@@ -302,8 +302,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
|
||||
size_t data_len;
|
||||
|
||||
g_assert(words[1] && words[2] && words[3]);
|
||||
addr = strtoul(words[1], NULL, 0);
|
||||
len = strtoul(words[2], NULL, 0);
|
||||
addr = strtoull(words[1], NULL, 0);
|
||||
len = strtoull(words[2], NULL, 0);
|
||||
|
||||
data_len = strlen(words[3]);
|
||||
if (data_len < 3) {
|
||||
|
43
savevm.c
43
savevm.c
@@ -140,6 +140,34 @@ typedef struct QEMUFileSocket
|
||||
QEMUFile *file;
|
||||
} QEMUFileSocket;
|
||||
|
||||
typedef struct {
|
||||
Coroutine *co;
|
||||
int fd;
|
||||
} FDYieldUntilData;
|
||||
|
||||
static void fd_coroutine_enter(void *opaque)
|
||||
{
|
||||
FDYieldUntilData *data = opaque;
|
||||
qemu_set_fd_handler(data->fd, NULL, NULL, NULL);
|
||||
qemu_coroutine_enter(data->co, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Yield until a file descriptor becomes readable
|
||||
*
|
||||
* Note that this function clobbers the handlers for the file descriptor.
|
||||
*/
|
||||
static void coroutine_fn yield_until_fd_readable(int fd)
|
||||
{
|
||||
FDYieldUntilData data;
|
||||
|
||||
assert(qemu_in_coroutine());
|
||||
data.co = qemu_coroutine_self();
|
||||
data.fd = fd;
|
||||
qemu_set_fd_handler(fd, fd_coroutine_enter, NULL, &data);
|
||||
qemu_coroutine_yield();
|
||||
}
|
||||
|
||||
static int socket_get_fd(void *opaque)
|
||||
{
|
||||
QEMUFileSocket *s = opaque;
|
||||
@@ -158,8 +186,7 @@ static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
|
||||
break;
|
||||
}
|
||||
if (socket_error() == EAGAIN) {
|
||||
assert(qemu_in_coroutine());
|
||||
qemu_coroutine_yield();
|
||||
yield_until_fd_readable(s->fd);
|
||||
} else if (socket_error() != EINTR) {
|
||||
break;
|
||||
}
|
||||
@@ -205,8 +232,7 @@ static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
|
||||
break;
|
||||
}
|
||||
if (errno == EAGAIN) {
|
||||
assert(qemu_in_coroutine());
|
||||
qemu_coroutine_yield();
|
||||
yield_until_fd_readable(fileno(fp));
|
||||
} else if (errno != EINTR) {
|
||||
break;
|
||||
}
|
||||
@@ -647,9 +673,14 @@ int qemu_get_byte(QEMUFile *f)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int64_t qemu_ftell(QEMUFile *f)
|
||||
int64_t qemu_ftell(QEMUFile *f)
|
||||
{
|
||||
return f->buf_offset - f->buf_size + f->buf_index;
|
||||
/* buf_offset excludes buffer for writing but includes it for reading */
|
||||
if (f->is_write) {
|
||||
return f->buf_offset + f->buf_index;
|
||||
} else {
|
||||
return f->buf_offset - f->buf_size + f->buf_index;
|
||||
}
|
||||
}
|
||||
|
||||
int qemu_file_rate_limit(QEMUFile *f)
|
||||
|
@@ -1333,7 +1333,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
|
||||
|
||||
numvalue = strtoul(val, &err, 0);
|
||||
if (!*val || *err) {
|
||||
error_setg(errp, "bad numerical value %s\n", val);
|
||||
error_setg(errp, "bad numerical value %s", val);
|
||||
goto out;
|
||||
}
|
||||
if (numvalue < 0x80000000) {
|
||||
@@ -1355,7 +1355,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
|
||||
tsc_freq = strtosz_suffix_unit(val, &err,
|
||||
STRTOSZ_DEFSUFFIX_B, 1000);
|
||||
if (tsc_freq < 0 || *err) {
|
||||
error_setg(errp, "bad numerical value %s\n", val);
|
||||
error_setg(errp, "bad numerical value %s", val);
|
||||
goto out;
|
||||
}
|
||||
snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
|
||||
@@ -1364,12 +1364,12 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
|
||||
char *err;
|
||||
numvalue = strtoul(val, &err, 0);
|
||||
if (!*val || *err) {
|
||||
error_setg(errp, "bad numerical value %s\n", val);
|
||||
error_setg(errp, "bad numerical value %s", val);
|
||||
goto out;
|
||||
}
|
||||
hyperv_set_spinlock_retries(numvalue);
|
||||
} else {
|
||||
error_setg(errp, "unrecognized feature %s\n", featurestr);
|
||||
error_setg(errp, "unrecognized feature %s", featurestr);
|
||||
goto out;
|
||||
}
|
||||
} else if (!strcmp(featurestr, "check")) {
|
||||
@@ -1382,7 +1382,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
|
||||
hyperv_enable_vapic_recommended(true);
|
||||
} else {
|
||||
error_setg(errp, "feature string `%s' not in format (+feature|"
|
||||
"-feature|feature=xyz)\n", featurestr);
|
||||
"-feature|feature=xyz)", featurestr);
|
||||
goto out;
|
||||
}
|
||||
if (error_is_set(errp)) {
|
||||
|
@@ -9806,7 +9806,7 @@ static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
|
||||
((opc->handler.type2 & def->insns_flags2) != 0)) {
|
||||
if (register_insn(env->opcodes, opc) < 0) {
|
||||
error_setg(errp, "ERROR initializing PowerPC instruction "
|
||||
"0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
|
||||
"0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
|
||||
opc->opc3);
|
||||
return;
|
||||
}
|
||||
|
@@ -1001,7 +1001,7 @@ static inline void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id,
|
||||
uint32_t io_int_parm, uint32_t io_int_word)
|
||||
{
|
||||
CPUS390XState *env = &cpu->env;
|
||||
int isc = ffs(io_int_word << 2) - 1;
|
||||
int isc = IO_INT_WORD_ISC(io_int_word);
|
||||
|
||||
if (env->io_index[isc] == MAX_IO_QUEUE - 1) {
|
||||
/* ugh - can't queue anymore. Let's drop. */
|
||||
|
@@ -617,7 +617,6 @@ static void do_ext_interrupt(CPUS390XState *env)
|
||||
|
||||
static void do_io_interrupt(CPUS390XState *env)
|
||||
{
|
||||
uint64_t mask = 0, addr = 0;
|
||||
LowCore *lowcore;
|
||||
IOIntQueue *q;
|
||||
uint8_t isc;
|
||||
@@ -629,6 +628,8 @@ static void do_io_interrupt(CPUS390XState *env)
|
||||
}
|
||||
|
||||
for (isc = 0; isc < ARRAY_SIZE(env->io_index); isc++) {
|
||||
uint64_t isc_bits;
|
||||
|
||||
if (env->io_index[isc] < 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -638,40 +639,44 @@ static void do_io_interrupt(CPUS390XState *env)
|
||||
}
|
||||
|
||||
q = &env->io_queue[env->io_index[isc]][isc];
|
||||
if (!(env->cregs[6] & q->word)) {
|
||||
isc_bits = ISC_TO_ISC_BITS(IO_INT_WORD_ISC(q->word));
|
||||
if (!(env->cregs[6] & isc_bits)) {
|
||||
disable = 0;
|
||||
continue;
|
||||
}
|
||||
found = 1;
|
||||
lowcore = cpu_map_lowcore(env);
|
||||
if (!found) {
|
||||
uint64_t mask, addr;
|
||||
|
||||
lowcore->subchannel_id = cpu_to_be16(q->id);
|
||||
lowcore->subchannel_nr = cpu_to_be16(q->nr);
|
||||
lowcore->io_int_parm = cpu_to_be32(q->parm);
|
||||
lowcore->io_int_word = cpu_to_be32(q->word);
|
||||
lowcore->io_old_psw.mask = cpu_to_be64(get_psw_mask(env));
|
||||
lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
|
||||
mask = be64_to_cpu(lowcore->io_new_psw.mask);
|
||||
addr = be64_to_cpu(lowcore->io_new_psw.addr);
|
||||
found = 1;
|
||||
lowcore = cpu_map_lowcore(env);
|
||||
|
||||
cpu_unmap_lowcore(lowcore);
|
||||
lowcore->subchannel_id = cpu_to_be16(q->id);
|
||||
lowcore->subchannel_nr = cpu_to_be16(q->nr);
|
||||
lowcore->io_int_parm = cpu_to_be32(q->parm);
|
||||
lowcore->io_int_word = cpu_to_be32(q->word);
|
||||
lowcore->io_old_psw.mask = cpu_to_be64(get_psw_mask(env));
|
||||
lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
|
||||
mask = be64_to_cpu(lowcore->io_new_psw.mask);
|
||||
addr = be64_to_cpu(lowcore->io_new_psw.addr);
|
||||
|
||||
env->io_index[isc]--;
|
||||
cpu_unmap_lowcore(lowcore);
|
||||
|
||||
env->io_index[isc]--;
|
||||
|
||||
DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,
|
||||
env->psw.mask, env->psw.addr);
|
||||
load_psw(env, mask, addr);
|
||||
}
|
||||
if (env->io_index[isc] >= 0) {
|
||||
disable = 0;
|
||||
}
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (disable) {
|
||||
env->pending_int &= ~INTERRUPT_IO;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,
|
||||
env->psw.mask, env->psw.addr);
|
||||
load_psw(env, mask, addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_mchk_interrupt(CPUS390XState *env)
|
||||
|
@@ -209,6 +209,9 @@ typedef struct IOIntCode {
|
||||
#define IOINST_SCHID_SSID(_schid) ((_schid & 0x00060000) >> 17)
|
||||
#define IOINST_SCHID_NR(_schid) (_schid & 0x0000ffff)
|
||||
|
||||
#define IO_INT_WORD_ISC(_int_word) ((_int_word & 0x38000000) >> 24)
|
||||
#define ISC_TO_ISC_BITS(_isc) ((0x80 >> _isc) << 24)
|
||||
|
||||
int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
|
||||
int *schid);
|
||||
int ioinst_handle_xsch(CPUS390XState *env, uint64_t reg1);
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "libqtest.h"
|
||||
|
||||
enum OMAPI2CRegisters {
|
||||
@@ -48,12 +49,35 @@ typedef struct OMAPI2C {
|
||||
} OMAPI2C;
|
||||
|
||||
|
||||
/* FIXME Use TBD readw qtest API */
|
||||
static inline uint16_t readw(uint64_t addr)
|
||||
{
|
||||
uint16_t data;
|
||||
|
||||
memread(addr, &data, 2);
|
||||
return le16_to_cpu(data);
|
||||
}
|
||||
|
||||
/* FIXME Use TBD writew qtest API */
|
||||
static inline void writew(uint64_t addr, uint16_t data)
|
||||
{
|
||||
data = cpu_to_le16(data);
|
||||
memwrite(addr, &data, 2);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
#undef memread
|
||||
#undef memwrite
|
||||
#pragma GCC poison memread
|
||||
#pragma GCC poison memwrite
|
||||
#endif
|
||||
|
||||
static void omap_i2c_set_slave_addr(OMAPI2C *s, uint8_t addr)
|
||||
{
|
||||
uint16_t data = addr;
|
||||
|
||||
memwrite(s->addr + OMAP_I2C_SA, &data, 2);
|
||||
memread(s->addr + OMAP_I2C_SA, &data, 2);
|
||||
writew(s->addr + OMAP_I2C_SA, data);
|
||||
data = readw(s->addr + OMAP_I2C_SA);
|
||||
g_assert_cmphex(data, ==, addr);
|
||||
}
|
||||
|
||||
@@ -66,36 +90,38 @@ static void omap_i2c_send(I2CAdapter *i2c, uint8_t addr,
|
||||
omap_i2c_set_slave_addr(s, addr);
|
||||
|
||||
data = len;
|
||||
memwrite(s->addr + OMAP_I2C_CNT, &data, 2);
|
||||
writew(s->addr + OMAP_I2C_CNT, data);
|
||||
|
||||
data = OMAP_I2C_CON_I2C_EN |
|
||||
OMAP_I2C_CON_TRX |
|
||||
OMAP_I2C_CON_MST |
|
||||
OMAP_I2C_CON_STT |
|
||||
OMAP_I2C_CON_STP;
|
||||
memwrite(s->addr + OMAP_I2C_CON, &data, 2);
|
||||
memread(s->addr + OMAP_I2C_CON, &data, 2);
|
||||
writew(s->addr + OMAP_I2C_CON, data);
|
||||
data = readw(s->addr + OMAP_I2C_CON);
|
||||
g_assert((data & OMAP_I2C_CON_STP) != 0);
|
||||
|
||||
memread(s->addr + OMAP_I2C_STAT, &data, 2);
|
||||
data = readw(s->addr + OMAP_I2C_STAT);
|
||||
g_assert((data & OMAP_I2C_STAT_NACK) == 0);
|
||||
|
||||
while (len > 1) {
|
||||
memread(s->addr + OMAP_I2C_STAT, &data, 2);
|
||||
data = readw(s->addr + OMAP_I2C_STAT);
|
||||
g_assert((data & OMAP_I2C_STAT_XRDY) != 0);
|
||||
|
||||
memwrite(s->addr + OMAP_I2C_DATA, buf, 2);
|
||||
data = buf[0] | ((uint16_t)buf[1] << 8);
|
||||
writew(s->addr + OMAP_I2C_DATA, data);
|
||||
buf = (uint8_t *)buf + 2;
|
||||
len -= 2;
|
||||
}
|
||||
if (len == 1) {
|
||||
memread(s->addr + OMAP_I2C_STAT, &data, 2);
|
||||
data = readw(s->addr + OMAP_I2C_STAT);
|
||||
g_assert((data & OMAP_I2C_STAT_XRDY) != 0);
|
||||
|
||||
memwrite(s->addr + OMAP_I2C_DATA, buf, 1);
|
||||
data = buf[0];
|
||||
writew(s->addr + OMAP_I2C_DATA, data);
|
||||
}
|
||||
|
||||
memread(s->addr + OMAP_I2C_CON, &data, 2);
|
||||
data = readw(s->addr + OMAP_I2C_CON);
|
||||
g_assert((data & OMAP_I2C_CON_STP) == 0);
|
||||
}
|
||||
|
||||
@@ -108,42 +134,46 @@ static void omap_i2c_recv(I2CAdapter *i2c, uint8_t addr,
|
||||
omap_i2c_set_slave_addr(s, addr);
|
||||
|
||||
data = len;
|
||||
memwrite(s->addr + OMAP_I2C_CNT, &data, 2);
|
||||
writew(s->addr + OMAP_I2C_CNT, data);
|
||||
|
||||
data = OMAP_I2C_CON_I2C_EN |
|
||||
OMAP_I2C_CON_MST |
|
||||
OMAP_I2C_CON_STT |
|
||||
OMAP_I2C_CON_STP;
|
||||
memwrite(s->addr + OMAP_I2C_CON, &data, 2);
|
||||
memread(s->addr + OMAP_I2C_CON, &data, 2);
|
||||
writew(s->addr + OMAP_I2C_CON, data);
|
||||
data = readw(s->addr + OMAP_I2C_CON);
|
||||
g_assert((data & OMAP_I2C_CON_STP) == 0);
|
||||
|
||||
memread(s->addr + OMAP_I2C_STAT, &data, 2);
|
||||
data = readw(s->addr + OMAP_I2C_STAT);
|
||||
g_assert((data & OMAP_I2C_STAT_NACK) == 0);
|
||||
|
||||
memread(s->addr + OMAP_I2C_CNT, &data, 2);
|
||||
data = readw(s->addr + OMAP_I2C_CNT);
|
||||
g_assert_cmpuint(data, ==, len);
|
||||
|
||||
while (len > 0) {
|
||||
memread(s->addr + OMAP_I2C_STAT, &data, 2);
|
||||
data = readw(s->addr + OMAP_I2C_STAT);
|
||||
g_assert((data & OMAP_I2C_STAT_RRDY) != 0);
|
||||
g_assert((data & OMAP_I2C_STAT_ROVR) == 0);
|
||||
|
||||
memread(s->addr + OMAP_I2C_DATA, &data, 2);
|
||||
data = readw(s->addr + OMAP_I2C_DATA);
|
||||
|
||||
stat = readw(s->addr + OMAP_I2C_STAT);
|
||||
|
||||
memread(s->addr + OMAP_I2C_STAT, &stat, 2);
|
||||
if (unlikely(len == 1)) {
|
||||
*buf = data & 0xf;
|
||||
g_assert((stat & OMAP_I2C_STAT_SBD) != 0);
|
||||
|
||||
buf[0] = data & 0xff;
|
||||
buf++;
|
||||
len--;
|
||||
} else {
|
||||
memcpy(buf, &data, 2);
|
||||
buf[0] = data & 0xff;
|
||||
buf[1] = data >> 8;
|
||||
buf += 2;
|
||||
len -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
memread(s->addr + OMAP_I2C_CON, &data, 2);
|
||||
data = readw(s->addr + OMAP_I2C_CON);
|
||||
g_assert((data & OMAP_I2C_CON_STP) == 0);
|
||||
}
|
||||
|
||||
@@ -159,7 +189,7 @@ I2CAdapter *omap_i2c_create(uint64_t addr)
|
||||
i2c->recv = omap_i2c_recv;
|
||||
|
||||
/* verify the mmio address by looking for a known signature */
|
||||
memread(addr + OMAP_I2C_REV, &data, 2);
|
||||
data = readw(addr + OMAP_I2C_REV);
|
||||
g_assert_cmphex(data, ==, 0x34);
|
||||
|
||||
return i2c;
|
||||
|
@@ -109,7 +109,6 @@ void qtest_outl(QTestState *s, uint16_t addr, uint32_t value);
|
||||
* qtest_inb:
|
||||
* @s: QTestState instance to operate on.
|
||||
* @addr: I/O port to read from.
|
||||
* @value: Value being written.
|
||||
*
|
||||
* Returns an 8-bit value from an I/O port.
|
||||
*/
|
||||
@@ -119,7 +118,6 @@ uint8_t qtest_inb(QTestState *s, uint16_t addr);
|
||||
* qtest_inw:
|
||||
* @s: QTestState instance to operate on.
|
||||
* @addr: I/O port to read from.
|
||||
* @value: Value being written.
|
||||
*
|
||||
* Returns a 16-bit value from an I/O port.
|
||||
*/
|
||||
@@ -129,7 +127,6 @@ uint16_t qtest_inw(QTestState *s, uint16_t addr);
|
||||
* qtest_inl:
|
||||
* @s: QTestState instance to operate on.
|
||||
* @addr: I/O port to read from.
|
||||
* @value: Value being written.
|
||||
*
|
||||
* Returns a 32-bit value from an I/O port.
|
||||
*/
|
||||
@@ -279,7 +276,6 @@ void qtest_add_func(const char *str, void (*fn));
|
||||
/**
|
||||
* inb:
|
||||
* @addr: I/O port to read from.
|
||||
* @value: Value being written.
|
||||
*
|
||||
* Returns an 8-bit value from an I/O port.
|
||||
*/
|
||||
@@ -288,7 +284,6 @@ void qtest_add_func(const char *str, void (*fn));
|
||||
/**
|
||||
* inw:
|
||||
* @addr: I/O port to read from.
|
||||
* @value: Value being written.
|
||||
*
|
||||
* Returns a 16-bit value from an I/O port.
|
||||
*/
|
||||
@@ -297,7 +292,6 @@ void qtest_add_func(const char *str, void (*fn));
|
||||
/**
|
||||
* inl:
|
||||
* @addr: I/O port to read from.
|
||||
* @value: Value being written.
|
||||
*
|
||||
* Returns a 32-bit value from an I/O port.
|
||||
*/
|
||||
|
@@ -174,7 +174,6 @@ static void test_visitor_in_fuzz(TestInputVisitorData *data,
|
||||
double nres;
|
||||
char *sres;
|
||||
EnumOne eres;
|
||||
Error *errp = NULL;
|
||||
Visitor *v;
|
||||
unsigned int i;
|
||||
char buf[10000];
|
||||
@@ -193,21 +192,22 @@ static void test_visitor_in_fuzz(TestInputVisitorData *data,
|
||||
}
|
||||
|
||||
v = visitor_input_test_init(data, buf);
|
||||
visit_type_int(v, &ires, NULL, &errp);
|
||||
visit_type_int(v, &ires, NULL, NULL);
|
||||
|
||||
v = visitor_input_test_init(data, buf);
|
||||
visit_type_bool(v, &bres, NULL, &errp);
|
||||
visit_type_bool(v, &bres, NULL, NULL);
|
||||
visitor_input_teardown(data, NULL);
|
||||
|
||||
v = visitor_input_test_init(data, buf);
|
||||
visit_type_number(v, &nres, NULL, &errp);
|
||||
visit_type_number(v, &nres, NULL, NULL);
|
||||
|
||||
v = visitor_input_test_init(data, buf);
|
||||
visit_type_str(v, &sres, NULL, &errp);
|
||||
sres = NULL;
|
||||
visit_type_str(v, &sres, NULL, NULL);
|
||||
g_free(sres);
|
||||
|
||||
v = visitor_input_test_init(data, buf);
|
||||
visit_type_EnumOne(v, &eres, NULL, &errp);
|
||||
visit_type_EnumOne(v, &eres, NULL, NULL);
|
||||
visitor_input_teardown(data, NULL);
|
||||
}
|
||||
}
|
||||
|
@@ -40,8 +40,18 @@
|
||||
* records to become available, writes them out, and then waits again.
|
||||
*/
|
||||
static GStaticMutex trace_lock = G_STATIC_MUTEX_INIT;
|
||||
|
||||
/* g_cond_new() was deprecated in glib 2.31 but we still need to support it */
|
||||
#if GLIB_CHECK_VERSION(2, 31, 0)
|
||||
static GCond the_trace_available_cond;
|
||||
static GCond the_trace_empty_cond;
|
||||
static GCond *trace_available_cond = &the_trace_available_cond;
|
||||
static GCond *trace_empty_cond = &the_trace_empty_cond;
|
||||
#else
|
||||
static GCond *trace_available_cond;
|
||||
static GCond *trace_empty_cond;
|
||||
#endif
|
||||
|
||||
static bool trace_available;
|
||||
static bool trace_writeout_enabled;
|
||||
|
||||
@@ -51,9 +61,9 @@ enum {
|
||||
};
|
||||
|
||||
uint8_t trace_buf[TRACE_BUF_LEN];
|
||||
static unsigned int trace_idx;
|
||||
static volatile gint trace_idx;
|
||||
static unsigned int writeout_idx;
|
||||
static int dropped_events;
|
||||
static volatile gint dropped_events;
|
||||
static FILE *trace_fp;
|
||||
static char *trace_file_name;
|
||||
|
||||
@@ -267,7 +277,7 @@ void trace_record_finish(TraceBufferRecord *rec)
|
||||
record.event |= TRACE_RECORD_VALID;
|
||||
write_to_buffer(rec->tbuf_idx, &record, sizeof(TraceRecord));
|
||||
|
||||
if ((g_atomic_int_get(&trace_idx) - writeout_idx)
|
||||
if (((unsigned int)g_atomic_int_get(&trace_idx) - writeout_idx)
|
||||
> TRACE_BUF_FLUSH_THRESHOLD) {
|
||||
flush_trace_file(false);
|
||||
}
|
||||
@@ -397,7 +407,13 @@ static GThread *trace_thread_create(GThreadFunc fn)
|
||||
sigfillset(&set);
|
||||
pthread_sigmask(SIG_SETMASK, &set, &oldset);
|
||||
#endif
|
||||
|
||||
#if GLIB_CHECK_VERSION(2, 31, 0)
|
||||
thread = g_thread_new("trace-thread", fn, NULL);
|
||||
#else
|
||||
thread = g_thread_create(fn, NULL, FALSE, NULL);
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||
#endif
|
||||
@@ -418,8 +434,10 @@ bool trace_backend_init(const char *events, const char *file)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2, 31, 0)
|
||||
trace_available_cond = g_cond_new();
|
||||
trace_empty_cond = g_cond_new();
|
||||
#endif
|
||||
|
||||
thread = trace_thread_create(writeout_thread);
|
||||
if (!thread) {
|
||||
|
@@ -194,7 +194,7 @@ void qmp_screendump(const char *filename, Error **errp)
|
||||
if (consoles[0] && consoles[0]->hw_screen_dump) {
|
||||
consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, errp);
|
||||
} else {
|
||||
error_setg(errp, "device doesn't support screendump\n");
|
||||
error_setg(errp, "device doesn't support screendump");
|
||||
}
|
||||
|
||||
if (cswitch) {
|
||||
|
@@ -269,7 +269,7 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
|
||||
/* key down events */
|
||||
keycode = keycode_from_keyvalue(p->value);
|
||||
if (keycode < 0x01 || keycode > 0xff) {
|
||||
error_setg(errp, "invalid hex keycode 0x%x\n", keycode);
|
||||
error_setg(errp, "invalid hex keycode 0x%x", keycode);
|
||||
free_keycodes();
|
||||
return;
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ QemuOptsList *qemu_find_opts(const char *group)
|
||||
|
||||
ret = find_list(vm_config_groups, group, &local_err);
|
||||
if (error_is_set(&local_err)) {
|
||||
error_report("%s\n", error_get_pretty(local_err));
|
||||
error_report("%s", error_get_pretty(local_err));
|
||||
error_free(local_err);
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
|
||||
/* group with id */
|
||||
list = find_list(lists, group, &local_err);
|
||||
if (error_is_set(&local_err)) {
|
||||
error_report("%s\n", error_get_pretty(local_err));
|
||||
error_report("%s", error_get_pretty(local_err));
|
||||
error_free(local_err);
|
||||
goto out;
|
||||
}
|
||||
@@ -164,7 +164,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
|
||||
/* group without id */
|
||||
list = find_list(lists, group, &local_err);
|
||||
if (error_is_set(&local_err)) {
|
||||
error_report("%s\n", error_get_pretty(local_err));
|
||||
error_report("%s", error_get_pretty(local_err));
|
||||
error_free(local_err);
|
||||
goto out;
|
||||
}
|
||||
|
@@ -231,8 +231,10 @@ static void parse_option_size(const char *name, const char *value,
|
||||
break;
|
||||
default:
|
||||
error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size");
|
||||
#if 0 /* conversion from qerror_report() to error_set() broke this: */
|
||||
error_printf_unless_qmp("You may use k, M, G or T suffixes for "
|
||||
"kilobytes, megabytes, gigabytes and terabytes.\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -771,7 +773,9 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
|
||||
if (id) {
|
||||
if (!id_wellformed(id)) {
|
||||
error_set(errp,QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
|
||||
#if 0 /* conversion from qerror_report() to error_set() broke this: */
|
||||
error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
opts = qemu_opts_find(list, id);
|
||||
|
@@ -720,7 +720,7 @@ int unix_connect_opts(QemuOpts *opts, Error **errp,
|
||||
int sock, rc;
|
||||
|
||||
if (NULL == path) {
|
||||
error_setg(errp, "unix connect: no path specified\n");
|
||||
error_setg(errp, "unix connect: no path specified");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -854,7 +854,7 @@ SocketAddress *socket_parse(const char *str, Error **errp)
|
||||
addr = g_new(SocketAddress, 1);
|
||||
if (strstart(str, "unix:", NULL)) {
|
||||
if (str[5] == '\0') {
|
||||
error_setg(errp, "invalid Unix socket address\n");
|
||||
error_setg(errp, "invalid Unix socket address");
|
||||
goto fail;
|
||||
} else {
|
||||
addr->kind = SOCKET_ADDRESS_KIND_UNIX;
|
||||
@@ -863,7 +863,7 @@ SocketAddress *socket_parse(const char *str, Error **errp)
|
||||
}
|
||||
} else if (strstart(str, "fd:", NULL)) {
|
||||
if (str[3] == '\0') {
|
||||
error_setg(errp, "invalid file descriptor address\n");
|
||||
error_setg(errp, "invalid file descriptor address");
|
||||
goto fail;
|
||||
} else {
|
||||
addr->kind = SOCKET_ADDRESS_KIND_FD;
|
||||
|
20
vl.c
20
vl.c
@@ -3135,8 +3135,10 @@ int main(int argc, char **argv, char **envp)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
qemu_opts_parse(qemu_find_opts("boot-opts"),
|
||||
optarg, 0);
|
||||
if (!qemu_opts_parse(qemu_find_opts("boot-opts"),
|
||||
optarg, 0)) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3334,7 +3336,6 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
opts = qemu_opts_parse(olist, optarg, 1);
|
||||
if (!opts) {
|
||||
fprintf(stderr, "parse error: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
@@ -3350,7 +3351,6 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
opts = qemu_opts_parse(olist, optarg, 1);
|
||||
if (!opts) {
|
||||
fprintf(stderr, "parse error: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -3521,7 +3521,6 @@ int main(int argc, char **argv, char **envp)
|
||||
olist = qemu_find_opts("machine");
|
||||
opts = qemu_opts_parse(olist, optarg, 1);
|
||||
if (!opts) {
|
||||
fprintf(stderr, "parse error: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
optarg = qemu_opt_get(opts, "type");
|
||||
@@ -3626,6 +3625,9 @@ int main(int argc, char **argv, char **envp)
|
||||
exit(1);
|
||||
}
|
||||
opts = qemu_opts_parse(qemu_find_opts("option-rom"), optarg, 1);
|
||||
if (!opts) {
|
||||
exit(1);
|
||||
}
|
||||
option_rom[nb_option_roms].name = qemu_opt_get(opts, "romfile");
|
||||
option_rom[nb_option_roms].bootindex =
|
||||
qemu_opt_get_number(opts, "bootindex", -1);
|
||||
@@ -3755,7 +3757,6 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
opts = qemu_opts_parse(olist, optarg, 0);
|
||||
if (!opts) {
|
||||
fprintf(stderr, "parse error: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
@@ -3784,14 +3785,14 @@ int main(int argc, char **argv, char **envp)
|
||||
case QEMU_OPTION_sandbox:
|
||||
opts = qemu_opts_parse(qemu_find_opts("sandbox"), optarg, 1);
|
||||
if (!opts) {
|
||||
exit(0);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case QEMU_OPTION_add_fd:
|
||||
#ifndef _WIN32
|
||||
opts = qemu_opts_parse(qemu_find_opts("add-fd"), optarg, 0);
|
||||
if (!opts) {
|
||||
exit(0);
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
error_report("File descriptor passing is disabled on this "
|
||||
@@ -3801,6 +3802,9 @@ int main(int argc, char **argv, char **envp)
|
||||
break;
|
||||
case QEMU_OPTION_object:
|
||||
opts = qemu_opts_parse(qemu_find_opts("object"), optarg, 1);
|
||||
if (!opts) {
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
os_parse_cmd_args(popt->index, optarg);
|
||||
|
Reference in New Issue
Block a user