Compare commits
62 Commits
pull-input
...
v1.5.2
Author | SHA1 | Date | |
---|---|---|---|
|
ff4be47d1b | ||
|
be161ae35d | ||
|
bb31546dfa | ||
|
af0bbf8eb8 | ||
|
31c6ed2077 | ||
|
c432c7d85a | ||
|
295d81c624 | ||
|
cc0bd7ec83 | ||
|
12e5b2b5da | ||
|
cb55efe6db | ||
|
1b94fc4b9a | ||
|
5e690bb974 | ||
|
129db3679c | ||
|
637d640fbb | ||
|
9c4f5dd03a | ||
|
3abd71cd98 | ||
|
5fcb9bf746 | ||
|
6c8cf5fd02 | ||
|
ce4e8f0d4c | ||
|
c683f1b934 | ||
|
75e4aa9405 | ||
|
055a7fce65 | ||
|
93bc624384 | ||
|
61fbaee1a7 | ||
|
685ee2d940 | ||
|
fa0f47d390 | ||
|
75525693cc | ||
|
02d26729ea | ||
|
2917f6bcd0 | ||
|
9534f66ac1 | ||
|
d208f05fd9 | ||
|
6b6f105349 | ||
|
3202c02817 | ||
|
5a893b0d37 | ||
|
0817fa9767 | ||
|
5810174865 | ||
|
eeaa8d33e4 | ||
|
c1270701c0 | ||
|
252a7c6e11 | ||
|
6f3718c73b | ||
|
1fb147f443 | ||
|
72762f2811 | ||
|
31ba7016d4 | ||
|
9ca80c7f29 | ||
|
a548bacfba | ||
|
9b5751ec09 | ||
|
032ce1baac | ||
|
baa8a8b444 | ||
|
327e75b537 | ||
|
9e7fdafc65 | ||
|
d503afb28d | ||
|
5b3ca29b95 | ||
|
7b9cdc5bba | ||
|
0565700d78 | ||
|
ddaa83eebe | ||
|
38ec6c1071 | ||
|
951411fa36 | ||
|
5c26608027 | ||
|
3541912190 | ||
|
749806d1a7 | ||
|
a6fc2cd986 | ||
|
eabdf85d86 |
5
Makefile
5
Makefile
@@ -306,10 +306,13 @@ install-doc: $(DOCS)
|
||||
$(INSTALL_DATA) QMP/qmp-commands.txt "$(DESTDIR)$(qemu_docdir)"
|
||||
ifdef CONFIG_POSIX
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
|
||||
$(INSTALL_DATA) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
|
||||
$(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1"
|
||||
ifneq ($(TOOLS),)
|
||||
$(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
|
||||
$(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
|
||||
endif
|
||||
endif
|
||||
ifdef CONFIG_VIRTFS
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
|
||||
$(INSTALL_DATA) fsdev/virtfs-proxy-helper.1 "$(DESTDIR)$(mandir)/man1"
|
||||
|
@@ -1029,7 +1029,7 @@ int qemu_uuid_parse(const char *str, uint8_t *uuid)
|
||||
return -1;
|
||||
}
|
||||
#ifdef TARGET_I386
|
||||
smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
|
||||
smbios_add_field(1, offsetof(struct smbios_type_1, uuid), uuid, 16);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -1053,7 +1053,6 @@ void do_smbios_option(const char *optarg)
|
||||
{
|
||||
#ifdef TARGET_I386
|
||||
if (smbios_entry_add(optarg) < 0) {
|
||||
fprintf(stderr, "Wrong smbios provided\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
@@ -25,11 +25,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef __OpenBSD__
|
||||
#include <soundcard.h>
|
||||
#else
|
||||
#include <sys/soundcard.h>
|
||||
#endif
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/host-utils.h"
|
||||
|
@@ -611,8 +611,6 @@ CharDriverState *chr_baum_init(void)
|
||||
|
||||
qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);
|
||||
|
||||
qemu_chr_be_generic_open(chr);
|
||||
|
||||
return chr;
|
||||
|
||||
fail:
|
||||
|
@@ -70,6 +70,7 @@ CharDriverState *qemu_chr_open_msmouse(void)
|
||||
chr = g_malloc0(sizeof(CharDriverState));
|
||||
chr->chr_write = msmouse_chr_write;
|
||||
chr->chr_close = msmouse_chr_close;
|
||||
chr->explicit_be_open = true;
|
||||
|
||||
qemu_add_mouse_event_handler(msmouse_event, chr, 0, "QEMU Microsoft Mouse");
|
||||
|
||||
|
131
block/iscsi.c
131
block/iscsi.c
@@ -218,10 +218,8 @@ iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
|
||||
if (status == SCSI_STATUS_CHECK_CONDITION
|
||||
&& acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
|
||||
&& acb->retries-- > 0) {
|
||||
if (acb->task != NULL) {
|
||||
scsi_free_scsi_task(acb->task);
|
||||
acb->task = NULL;
|
||||
}
|
||||
scsi_free_scsi_task(acb->task);
|
||||
acb->task = NULL;
|
||||
if (iscsi_aio_writev_acb(acb) == 0) {
|
||||
iscsi_set_events(acb->iscsilun);
|
||||
return;
|
||||
@@ -303,6 +301,7 @@ iscsi_aio_writev_acb(IscsiAIOCB *acb)
|
||||
acb);
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
scsi_free_scsi_task(acb->task);
|
||||
g_free(acb->buf);
|
||||
return -1;
|
||||
}
|
||||
@@ -333,9 +332,6 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
|
||||
acb->retries = ISCSI_CMD_RETRIES;
|
||||
|
||||
if (iscsi_aio_writev_acb(acb) != 0) {
|
||||
if (acb->task) {
|
||||
scsi_free_scsi_task(acb->task);
|
||||
}
|
||||
qemu_aio_release(acb);
|
||||
return NULL;
|
||||
}
|
||||
@@ -364,10 +360,8 @@ iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
|
||||
if (status == SCSI_STATUS_CHECK_CONDITION
|
||||
&& acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
|
||||
&& acb->retries-- > 0) {
|
||||
if (acb->task != NULL) {
|
||||
scsi_free_scsi_task(acb->task);
|
||||
acb->task = NULL;
|
||||
}
|
||||
scsi_free_scsi_task(acb->task);
|
||||
acb->task = NULL;
|
||||
if (iscsi_aio_readv_acb(acb) == 0) {
|
||||
iscsi_set_events(acb->iscsilun);
|
||||
return;
|
||||
@@ -445,6 +439,7 @@ iscsi_aio_readv_acb(IscsiAIOCB *acb)
|
||||
NULL,
|
||||
acb);
|
||||
if (ret != 0) {
|
||||
scsi_free_scsi_task(acb->task);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -480,9 +475,6 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
|
||||
acb->retries = ISCSI_CMD_RETRIES;
|
||||
|
||||
if (iscsi_aio_readv_acb(acb) != 0) {
|
||||
if (acb->task) {
|
||||
scsi_free_scsi_task(acb->task);
|
||||
}
|
||||
qemu_aio_release(acb);
|
||||
return NULL;
|
||||
}
|
||||
@@ -509,10 +501,8 @@ iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
|
||||
if (status == SCSI_STATUS_CHECK_CONDITION
|
||||
&& acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
|
||||
&& acb->retries-- > 0) {
|
||||
if (acb->task != NULL) {
|
||||
scsi_free_scsi_task(acb->task);
|
||||
acb->task = NULL;
|
||||
}
|
||||
scsi_free_scsi_task(acb->task);
|
||||
acb->task = NULL;
|
||||
if (iscsi_aio_flush_acb(acb) == 0) {
|
||||
iscsi_set_events(acb->iscsilun);
|
||||
return;
|
||||
@@ -589,10 +579,8 @@ iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
|
||||
if (status == SCSI_STATUS_CHECK_CONDITION
|
||||
&& acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
|
||||
&& acb->retries-- > 0) {
|
||||
if (acb->task != NULL) {
|
||||
scsi_free_scsi_task(acb->task);
|
||||
acb->task = NULL;
|
||||
}
|
||||
scsi_free_scsi_task(acb->task);
|
||||
acb->task = NULL;
|
||||
if (iscsi_aio_discard_acb(acb) == 0) {
|
||||
iscsi_set_events(acb->iscsilun);
|
||||
return;
|
||||
@@ -647,9 +635,6 @@ iscsi_aio_discard(BlockDriverState *bs,
|
||||
acb->retries = ISCSI_CMD_RETRIES;
|
||||
|
||||
if (iscsi_aio_discard_acb(acb) != 0) {
|
||||
if (acb->task) {
|
||||
scsi_free_scsi_task(acb->task);
|
||||
}
|
||||
qemu_aio_release(acb);
|
||||
return NULL;
|
||||
}
|
||||
@@ -946,60 +931,58 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
|
||||
int ret = 0;
|
||||
int retries = ISCSI_CMD_RETRIES;
|
||||
|
||||
try_again:
|
||||
switch (iscsilun->type) {
|
||||
case TYPE_DISK:
|
||||
task = iscsi_readcapacity16_sync(iscsilun->iscsi, iscsilun->lun);
|
||||
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
|
||||
if (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION
|
||||
&& task->sense.key == SCSI_SENSE_UNIT_ATTENTION
|
||||
&& retries-- > 0) {
|
||||
scsi_free_scsi_task(task);
|
||||
goto try_again;
|
||||
}
|
||||
error_report("iSCSI: failed to send readcapacity16 command.");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
do {
|
||||
if (task != NULL) {
|
||||
scsi_free_scsi_task(task);
|
||||
task = NULL;
|
||||
}
|
||||
rc16 = scsi_datain_unmarshall(task);
|
||||
if (rc16 == NULL) {
|
||||
error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
iscsilun->block_size = rc16->block_length;
|
||||
iscsilun->num_blocks = rc16->returned_lba + 1;
|
||||
break;
|
||||
case TYPE_ROM:
|
||||
task = iscsi_readcapacity10_sync(iscsilun->iscsi, iscsilun->lun, 0, 0);
|
||||
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
|
||||
error_report("iSCSI: failed to send readcapacity10 command.");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
rc10 = scsi_datain_unmarshall(task);
|
||||
if (rc10 == NULL) {
|
||||
error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
iscsilun->block_size = rc10->block_size;
|
||||
if (rc10->lba == 0) {
|
||||
/* blank disk loaded */
|
||||
iscsilun->num_blocks = 0;
|
||||
} else {
|
||||
iscsilun->num_blocks = rc10->lba + 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
switch (iscsilun->type) {
|
||||
case TYPE_DISK:
|
||||
task = iscsi_readcapacity16_sync(iscsilun->iscsi, iscsilun->lun);
|
||||
if (task != NULL && task->status == SCSI_STATUS_GOOD) {
|
||||
rc16 = scsi_datain_unmarshall(task);
|
||||
if (rc16 == NULL) {
|
||||
error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
iscsilun->block_size = rc16->block_length;
|
||||
iscsilun->num_blocks = rc16->returned_lba + 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TYPE_ROM:
|
||||
task = iscsi_readcapacity10_sync(iscsilun->iscsi, iscsilun->lun, 0, 0);
|
||||
if (task != NULL && task->status == SCSI_STATUS_GOOD) {
|
||||
rc10 = scsi_datain_unmarshall(task);
|
||||
if (rc10 == NULL) {
|
||||
error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
iscsilun->block_size = rc10->block_size;
|
||||
if (rc10->lba == 0) {
|
||||
/* blank disk loaded */
|
||||
iscsilun->num_blocks = 0;
|
||||
} else {
|
||||
iscsilun->num_blocks = rc10->lba + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} while (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION
|
||||
&& task->sense.key == SCSI_SENSE_UNIT_ATTENTION
|
||||
&& retries-- > 0);
|
||||
|
||||
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
|
||||
error_report("iSCSI: failed to send readcapacity10 command.");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (task) {
|
||||
scsi_free_scsi_task(task);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
11
block/nbd.c
11
block/nbd.c
@@ -118,13 +118,22 @@ static int nbd_parse_uri(const char *filename, QDict *options)
|
||||
}
|
||||
qdict_put(options, "path", qstring_from_str(qp->p[0].value));
|
||||
} else {
|
||||
QString *host;
|
||||
/* nbd[+tcp]://host[:port]/export */
|
||||
if (!uri->server) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
qdict_put(options, "host", qstring_from_str(uri->server));
|
||||
/* strip braces from literal IPv6 address */
|
||||
if (uri->server[0] == '[') {
|
||||
host = qstring_from_substr(uri->server, 1,
|
||||
strlen(uri->server) - 2);
|
||||
} else {
|
||||
host = qstring_from_str(uri->server);
|
||||
}
|
||||
|
||||
qdict_put(options, "host", host);
|
||||
if (uri->port) {
|
||||
char* port_str = g_strdup_printf("%d", uri->port);
|
||||
qdict_put(options, "port", qstring_from_str(port_str));
|
||||
|
@@ -507,8 +507,11 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (header.capacity == 0 && header.desc_offset) {
|
||||
return vmdk_open_desc_file(bs, flags, header.desc_offset << 9);
|
||||
if (header.capacity == 0) {
|
||||
int64_t desc_offset = le64_to_cpu(header.desc_offset);
|
||||
if (desc_offset) {
|
||||
return vmdk_open_desc_file(bs, flags, desc_offset << 9);
|
||||
}
|
||||
}
|
||||
|
||||
if (le64_to_cpu(header.gd_offset) == VMDK4_GD_AT_END) {
|
||||
|
@@ -1108,6 +1108,10 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
*/
|
||||
if (bdrv_get_attached_dev(bs)) {
|
||||
bdrv_make_anon(bs);
|
||||
|
||||
/* Further I/O must not pause the guest */
|
||||
bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
|
||||
BLOCKDEV_ON_ERROR_REPORT);
|
||||
} else {
|
||||
drive_uninit(drive_get_by_blockdev(bs));
|
||||
}
|
||||
|
5
configure
vendored
5
configure
vendored
@@ -468,9 +468,8 @@ NetBSD)
|
||||
OpenBSD)
|
||||
bsd="yes"
|
||||
make="${MAKE-gmake}"
|
||||
audio_drv_list="oss"
|
||||
audio_possible_drivers="oss sdl esd"
|
||||
oss_lib="-lossaudio"
|
||||
audio_drv_list="sdl"
|
||||
audio_possible_drivers="sdl esd"
|
||||
;;
|
||||
Darwin)
|
||||
bsd="yes"
|
||||
|
@@ -185,6 +185,8 @@ Remove host block device. The result is that guest generated IO is no longer
|
||||
submitted against the host device underlying the disk. Once a drive has
|
||||
been deleted, the QEMU Block layer returns -EIO which results in IO
|
||||
errors in the guest for applications that are reading/writing to the device.
|
||||
These errors are always reported to the guest, regardless of the drive's error
|
||||
actions (drive options rerror, werror).
|
||||
ETEXI
|
||||
|
||||
{
|
||||
|
@@ -284,7 +284,7 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
|
||||
if ((fs_ctx->export_flags & V9FS_SM_MAPPED) ||
|
||||
(fs_ctx->export_flags & V9FS_SM_MAPPED_FILE)) {
|
||||
int fd;
|
||||
fd = open(rpath(fs_ctx, path, buffer), O_RDONLY);
|
||||
fd = open(rpath(fs_ctx, path, buffer), O_RDONLY | O_NOFOLLOW);
|
||||
if (fd == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
@@ -658,7 +658,7 @@ static mode_t v9mode_to_mode(uint32_t mode, V9fsString *extension)
|
||||
ret |= S_IFIFO;
|
||||
}
|
||||
if (mode & P9_STAT_MODE_DEVICE) {
|
||||
if (extension && extension->data[0] == 'c') {
|
||||
if (extension->size && extension->data[0] == 'c') {
|
||||
ret |= S_IFCHR;
|
||||
} else {
|
||||
ret |= S_IFBLK;
|
||||
|
@@ -515,7 +515,7 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
|
||||
l += snprintf(p + l, size - l, "%s", d);
|
||||
g_free(d);
|
||||
} else {
|
||||
l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
|
||||
return l;
|
||||
}
|
||||
}
|
||||
l += snprintf(p + l , size - l, "/");
|
||||
@@ -867,9 +867,17 @@ static void qbus_initfn(Object *obj)
|
||||
QTAILQ_INIT(&bus->children);
|
||||
}
|
||||
|
||||
static char *default_bus_get_fw_dev_path(DeviceState *dev)
|
||||
{
|
||||
return g_strdup(object_get_typename(OBJECT(dev)));
|
||||
}
|
||||
|
||||
static void bus_class_init(ObjectClass *class, void *data)
|
||||
{
|
||||
BusClass *bc = BUS_CLASS(class);
|
||||
|
||||
class->unparent = bus_unparent;
|
||||
bc->get_fw_dev_path = default_bus_get_fw_dev_path;
|
||||
}
|
||||
|
||||
static void qbus_finalize(Object *obj)
|
||||
|
@@ -514,8 +514,9 @@ static void axidma_write(void *opaque, hwaddr addr,
|
||||
break;
|
||||
}
|
||||
if (sid == 1 && d->notify) {
|
||||
d->notify(d->notify_opaque);
|
||||
StreamCanPushNotifyFn notifytmp = d->notify;
|
||||
d->notify = NULL;
|
||||
notifytmp(d->notify_opaque);
|
||||
}
|
||||
stream_update_irq(s);
|
||||
}
|
||||
|
@@ -927,6 +927,11 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
|
||||
DeviceState *icc_bridge;
|
||||
int64_t apic_id = x86_cpu_apic_id_from_index(id);
|
||||
|
||||
if (id < 0) {
|
||||
error_setg(errp, "Invalid CPU id: %" PRIi64, id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu_exists(apic_id)) {
|
||||
error_setg(errp, "Unable to add CPU: %" PRIi64
|
||||
", it already exists", id);
|
||||
|
@@ -102,9 +102,9 @@ static void pc_init1(MemoryRegion *system_memory,
|
||||
kvmclock_create();
|
||||
}
|
||||
|
||||
if (ram_size >= 0xe0000000 ) {
|
||||
above_4g_mem_size = ram_size - 0xe0000000;
|
||||
below_4g_mem_size = 0xe0000000;
|
||||
if (ram_size >= QEMU_BELOW_4G_RAM_END ) {
|
||||
above_4g_mem_size = ram_size - QEMU_BELOW_4G_RAM_END;
|
||||
below_4g_mem_size = QEMU_BELOW_4G_RAM_END;
|
||||
} else {
|
||||
above_4g_mem_size = 0;
|
||||
below_4g_mem_size = ram_size;
|
||||
|
@@ -13,6 +13,7 @@
|
||||
* GNU GPL, version 2 or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "qemu/error-report.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "hw/i386/smbios.h"
|
||||
#include "hw/loader.h"
|
||||
@@ -48,8 +49,7 @@ static int smbios_type4_count = 0;
|
||||
static void smbios_validate_table(void)
|
||||
{
|
||||
if (smbios_type4_count && smbios_type4_count != smp_cpus) {
|
||||
fprintf(stderr,
|
||||
"Number of SMBIOS Type 4 tables must match cpu count.\n");
|
||||
error_report("Number of SMBIOS Type 4 tables must match cpu count");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -82,16 +82,16 @@ static void smbios_check_collision(int type, int entry)
|
||||
if (entry == SMBIOS_TABLE_ENTRY && header->type == SMBIOS_FIELD_ENTRY) {
|
||||
struct smbios_field *field = (void *)header;
|
||||
if (type == field->type) {
|
||||
fprintf(stderr, "SMBIOS type %d field already defined, "
|
||||
"cannot add table\n", type);
|
||||
error_report("SMBIOS type %d field already defined, "
|
||||
"cannot add table", type);
|
||||
exit(1);
|
||||
}
|
||||
} else if (entry == SMBIOS_FIELD_ENTRY &&
|
||||
header->type == SMBIOS_TABLE_ENTRY) {
|
||||
struct smbios_structure_header *table = (void *)(header + 1);
|
||||
if (type == table->type) {
|
||||
fprintf(stderr, "SMBIOS type %d table already defined, "
|
||||
"cannot add field\n", type);
|
||||
error_report("SMBIOS type %d table already defined, "
|
||||
"cannot add field", type);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ static void smbios_check_collision(int type, int entry)
|
||||
}
|
||||
}
|
||||
|
||||
void smbios_add_field(int type, int offset, int len, void *data)
|
||||
void smbios_add_field(int type, int offset, const void *data, size_t len)
|
||||
{
|
||||
struct smbios_field *field;
|
||||
|
||||
@@ -127,24 +127,29 @@ void smbios_add_field(int type, int offset, int len, void *data)
|
||||
static void smbios_build_type_0_fields(const char *t)
|
||||
{
|
||||
char buf[1024];
|
||||
unsigned char major, minor;
|
||||
|
||||
if (get_param_value(buf, sizeof(buf), "vendor", t))
|
||||
smbios_add_field(0, offsetof(struct smbios_type_0, vendor_str),
|
||||
strlen(buf) + 1, buf);
|
||||
buf, strlen(buf) + 1);
|
||||
if (get_param_value(buf, sizeof(buf), "version", t))
|
||||
smbios_add_field(0, offsetof(struct smbios_type_0, bios_version_str),
|
||||
strlen(buf) + 1, buf);
|
||||
buf, strlen(buf) + 1);
|
||||
if (get_param_value(buf, sizeof(buf), "date", t))
|
||||
smbios_add_field(0, offsetof(struct smbios_type_0,
|
||||
bios_release_date_str),
|
||||
strlen(buf) + 1, buf);
|
||||
buf, strlen(buf) + 1);
|
||||
if (get_param_value(buf, sizeof(buf), "release", t)) {
|
||||
int major, minor;
|
||||
sscanf(buf, "%d.%d", &major, &minor);
|
||||
if (sscanf(buf, "%hhu.%hhu", &major, &minor) != 2) {
|
||||
error_report("Invalid release");
|
||||
exit(1);
|
||||
}
|
||||
smbios_add_field(0, offsetof(struct smbios_type_0,
|
||||
system_bios_major_release), 1, &major);
|
||||
system_bios_major_release),
|
||||
&major, 1);
|
||||
smbios_add_field(0, offsetof(struct smbios_type_0,
|
||||
system_bios_minor_release), 1, &minor);
|
||||
system_bios_minor_release),
|
||||
&minor, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,28 +159,28 @@ static void smbios_build_type_1_fields(const char *t)
|
||||
|
||||
if (get_param_value(buf, sizeof(buf), "manufacturer", t))
|
||||
smbios_add_field(1, offsetof(struct smbios_type_1, manufacturer_str),
|
||||
strlen(buf) + 1, buf);
|
||||
buf, strlen(buf) + 1);
|
||||
if (get_param_value(buf, sizeof(buf), "product", t))
|
||||
smbios_add_field(1, offsetof(struct smbios_type_1, product_name_str),
|
||||
strlen(buf) + 1, buf);
|
||||
buf, strlen(buf) + 1);
|
||||
if (get_param_value(buf, sizeof(buf), "version", t))
|
||||
smbios_add_field(1, offsetof(struct smbios_type_1, version_str),
|
||||
strlen(buf) + 1, buf);
|
||||
buf, strlen(buf) + 1);
|
||||
if (get_param_value(buf, sizeof(buf), "serial", t))
|
||||
smbios_add_field(1, offsetof(struct smbios_type_1, serial_number_str),
|
||||
strlen(buf) + 1, buf);
|
||||
buf, strlen(buf) + 1);
|
||||
if (get_param_value(buf, sizeof(buf), "uuid", t)) {
|
||||
if (qemu_uuid_parse(buf, qemu_uuid) != 0) {
|
||||
fprintf(stderr, "Invalid SMBIOS UUID string\n");
|
||||
error_report("Invalid UUID");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (get_param_value(buf, sizeof(buf), "sku", t))
|
||||
smbios_add_field(1, offsetof(struct smbios_type_1, sku_number_str),
|
||||
strlen(buf) + 1, buf);
|
||||
buf, strlen(buf) + 1);
|
||||
if (get_param_value(buf, sizeof(buf), "family", t))
|
||||
smbios_add_field(1, offsetof(struct smbios_type_1, family_str),
|
||||
strlen(buf) + 1, buf);
|
||||
buf, strlen(buf) + 1);
|
||||
}
|
||||
|
||||
int smbios_entry_add(const char *t)
|
||||
@@ -188,7 +193,7 @@ int smbios_entry_add(const char *t)
|
||||
int size = get_image_size(buf);
|
||||
|
||||
if (size == -1 || size < sizeof(struct smbios_structure_header)) {
|
||||
fprintf(stderr, "Cannot read smbios file %s\n", buf);
|
||||
error_report("Cannot read SMBIOS file %s", buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -204,7 +209,7 @@ int smbios_entry_add(const char *t)
|
||||
table->header.length = cpu_to_le16(sizeof(*table) + size);
|
||||
|
||||
if (load_image(buf, table->data) != size) {
|
||||
fprintf(stderr, "Failed to load smbios file %s", buf);
|
||||
error_report("Failed to load SMBIOS file %s", buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -230,12 +235,12 @@ int smbios_entry_add(const char *t)
|
||||
smbios_build_type_1_fields(t);
|
||||
return 0;
|
||||
default:
|
||||
fprintf(stderr, "Don't know how to build fields for SMBIOS type "
|
||||
"%ld\n", type);
|
||||
error_report("Don't know how to build fields for SMBIOS type %ld",
|
||||
type);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "smbios: must specify type= or file=\n");
|
||||
error_report("Must specify type= or file=");
|
||||
return -1;
|
||||
}
|
||||
|
@@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include "hw/hw.h"
|
||||
#include "hw/i386/pc.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/xen/xen_backend.h"
|
||||
#include "xen_domainbuild.h"
|
||||
@@ -31,27 +30,12 @@
|
||||
|
||||
static void xen_init_pv(QEMUMachineInitArgs *args)
|
||||
{
|
||||
const char *cpu_model = args->cpu_model;
|
||||
const char *kernel_filename = args->kernel_filename;
|
||||
const char *kernel_cmdline = args->kernel_cmdline;
|
||||
const char *initrd_filename = args->initrd_filename;
|
||||
X86CPU *cpu;
|
||||
CPUState *cs;
|
||||
DriveInfo *dinfo;
|
||||
int i;
|
||||
|
||||
/* Initialize a dummy CPU */
|
||||
if (cpu_model == NULL) {
|
||||
#ifdef TARGET_X86_64
|
||||
cpu_model = "qemu64";
|
||||
#else
|
||||
cpu_model = "qemu32";
|
||||
#endif
|
||||
}
|
||||
cpu = cpu_x86_init(cpu_model);
|
||||
cs = CPU(cpu);
|
||||
cs->halted = 1;
|
||||
|
||||
/* Initialize backend core & drivers */
|
||||
if (xen_be_init() != 0) {
|
||||
fprintf(stderr, "%s: xen backend core setup failed\n", __FUNCTION__);
|
||||
|
@@ -814,6 +814,7 @@ void ide_flush_cache(IDEState *s)
|
||||
return;
|
||||
}
|
||||
|
||||
s->status |= BUSY_STAT;
|
||||
bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
|
||||
bdrv_aio_flush(s->bs, ide_flush_cb, s);
|
||||
}
|
||||
|
@@ -735,6 +735,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
|
||||
|
||||
if (s->shmobj == NULL) {
|
||||
fprintf(stderr, "Must specify 'chardev' or 'shm' to ivshmem\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
IVSHMEM_DPRINTF("using shm_open (shm object = %s)\n", s->shmobj);
|
||||
|
@@ -2575,6 +2575,9 @@ static void rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val)
|
||||
/* this value is off by 16 */
|
||||
s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize);
|
||||
|
||||
/* more buffer space may be available so try to receive */
|
||||
qemu_flush_queued_packets(qemu_get_queue(s->nic));
|
||||
|
||||
DPRINTF(" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
|
||||
s->RxBufferSize, s->RxBufAddr, s->RxBufPtr);
|
||||
}
|
||||
|
@@ -1892,7 +1892,7 @@ static void vmxnet3_net_uninit(VMXNET3State *s)
|
||||
vmxnet_tx_pkt_reset(s->tx_pkt);
|
||||
vmxnet_tx_pkt_uninit(s->tx_pkt);
|
||||
vmxnet_rx_pkt_uninit(s->rx_pkt);
|
||||
qemu_del_net_client(qemu_get_queue(s->nic));
|
||||
qemu_del_nic(s->nic);
|
||||
}
|
||||
|
||||
static void vmxnet3_net_init(VMXNET3State *s)
|
||||
|
@@ -76,6 +76,7 @@ static void q35_host_class_init(ObjectClass *klass, void *data)
|
||||
|
||||
k->init = q35_host_init;
|
||||
dc->props = mch_props;
|
||||
dc->fw_name = "pci";
|
||||
}
|
||||
|
||||
static void q35_host_initfn(Object *obj)
|
||||
|
@@ -777,7 +777,7 @@ int css_do_tsch(SubchDev *sch, IRB *target_irb)
|
||||
(p->chars & PMCW_CHARS_MASK_CSENSE)) {
|
||||
irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
|
||||
memcpy(irb.ecw, sch->sense_data, sizeof(sch->sense_data));
|
||||
irb.esw[1] = 0x02000000 | (sizeof(sch->sense_data) << 8);
|
||||
irb.esw[1] = 0x01000000 | (sizeof(sch->sense_data) << 8);
|
||||
}
|
||||
}
|
||||
/* Store the irb to the guest. */
|
||||
|
@@ -300,7 +300,7 @@ static int s390_virtio_rng_init(VirtIOS390Device *s390_dev)
|
||||
}
|
||||
|
||||
object_property_set_link(OBJECT(dev),
|
||||
OBJECT(dev->vdev.conf.default_backend), "rng",
|
||||
OBJECT(dev->vdev.conf.rng), "rng",
|
||||
NULL);
|
||||
|
||||
return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
|
||||
|
@@ -328,10 +328,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
indicators = ldq_phys(ccw.cda);
|
||||
if (!indicators) {
|
||||
if (!ccw.cda) {
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
indicators = ldq_phys(ccw.cda);
|
||||
dev->indicators = indicators;
|
||||
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
|
||||
ret = 0;
|
||||
@@ -348,10 +348,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
indicators = ldq_phys(ccw.cda);
|
||||
if (!indicators) {
|
||||
if (!ccw.cda) {
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
indicators = ldq_phys(ccw.cda);
|
||||
dev->indicators2 = indicators;
|
||||
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
|
||||
ret = 0;
|
||||
@@ -744,7 +744,7 @@ static int virtio_ccw_rng_init(VirtioCcwDevice *ccw_dev)
|
||||
}
|
||||
|
||||
object_property_set_link(OBJECT(dev),
|
||||
OBJECT(dev->vdev.conf.default_backend), "rng",
|
||||
OBJECT(dev->vdev.conf.rng), "rng",
|
||||
NULL);
|
||||
|
||||
return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
|
||||
|
@@ -61,8 +61,9 @@ typedef struct SCSIDiskReq {
|
||||
BlockAcctCookie acct;
|
||||
} SCSIDiskReq;
|
||||
|
||||
#define SCSI_DISK_F_REMOVABLE 0
|
||||
#define SCSI_DISK_F_DPOFUA 1
|
||||
#define SCSI_DISK_F_REMOVABLE 0
|
||||
#define SCSI_DISK_F_DPOFUA 1
|
||||
#define SCSI_DISK_F_NO_REMOVABLE_DEVOPS 2
|
||||
|
||||
struct SCSIDiskState
|
||||
{
|
||||
@@ -1984,6 +1985,9 @@ static void scsi_disk_reset(DeviceState *dev)
|
||||
nb_sectors--;
|
||||
}
|
||||
s->qdev.max_lba = nb_sectors;
|
||||
/* reset tray statuses */
|
||||
s->tray_locked = 0;
|
||||
s->tray_open = 0;
|
||||
}
|
||||
|
||||
static void scsi_destroy(SCSIDevice *dev)
|
||||
@@ -2107,7 +2111,8 @@ static int scsi_initfn(SCSIDevice *dev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (s->features & (1 << SCSI_DISK_F_REMOVABLE)) {
|
||||
if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
|
||||
!(s->features & (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS))) {
|
||||
bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_disk_removable_block_ops, s);
|
||||
} else {
|
||||
bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_disk_block_ops, s);
|
||||
@@ -2319,6 +2324,12 @@ static int scsi_block_initfn(SCSIDevice *dev)
|
||||
} else {
|
||||
s->qdev.blocksize = 512;
|
||||
}
|
||||
|
||||
/* Makes the scsi-block device not removable by using HMP and QMP eject
|
||||
* command.
|
||||
*/
|
||||
s->features |= (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS);
|
||||
|
||||
return scsi_initfn(&s->qdev);
|
||||
}
|
||||
|
||||
|
@@ -174,6 +174,9 @@ static int execute_command(BlockDriverState *bdrv,
|
||||
r->io_header.flags |= SG_FLAG_DIRECT_IO;
|
||||
|
||||
r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
|
||||
if (r->req.aiocb == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -198,9 +201,10 @@ static void scsi_read_complete(void * opaque, int ret)
|
||||
scsi_command_complete(r, 0);
|
||||
} else {
|
||||
/* Snoop READ CAPACITY output to set the blocksize. */
|
||||
if (r->req.cmd.buf[0] == READ_CAPACITY_10) {
|
||||
if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
|
||||
(ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
|
||||
s->blocksize = ldl_be_p(&r->buf[4]);
|
||||
s->max_lba = ldl_be_p(&r->buf[0]);
|
||||
s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
|
||||
} else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
|
||||
(r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
|
||||
s->blocksize = ldl_be_p(&r->buf[8]);
|
||||
|
@@ -123,7 +123,7 @@ static void vhost_scsi_stop(VHostSCSI *s)
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||
int ret = 0;
|
||||
|
||||
if (!k->set_guest_notifiers) {
|
||||
if (k->set_guest_notifiers) {
|
||||
ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
|
||||
if (ret < 0) {
|
||||
error_report("vhost guest notifier cleanup failed: %d\n", ret);
|
||||
|
@@ -410,7 +410,7 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
|
||||
assert(p->ep->type != USB_ENDPOINT_XFER_ISOC);
|
||||
/* using async for interrupt packets breaks migration */
|
||||
assert(p->ep->type != USB_ENDPOINT_XFER_INT ||
|
||||
(dev->flags & USB_DEV_FLAG_IS_HOST));
|
||||
(dev->flags & (1 << USB_DEV_FLAG_IS_HOST)));
|
||||
usb_packet_set_state(p, USB_PACKET_ASYNC);
|
||||
QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
|
||||
} else if (p->status == USB_RET_ADD_TO_QUEUE) {
|
||||
|
@@ -385,7 +385,7 @@ out:
|
||||
static void usb_host_req_abort(USBHostRequest *r)
|
||||
{
|
||||
USBHostDevice *s = r->host;
|
||||
bool inflight = (r->p && r->p->state == USB_RET_ASYNC);
|
||||
bool inflight = (r->p && r->p->state == USB_PACKET_ASYNC);
|
||||
|
||||
if (inflight) {
|
||||
r->p->status = USB_RET_NODEV;
|
||||
|
@@ -161,10 +161,16 @@ static char *virtio_bus_get_dev_path(DeviceState *dev)
|
||||
return qdev_get_dev_path(proxy);
|
||||
}
|
||||
|
||||
static char *virtio_bus_get_fw_dev_path(DeviceState *dev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void virtio_bus_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
BusClass *bus_class = BUS_CLASS(klass);
|
||||
bus_class->get_dev_path = virtio_bus_get_dev_path;
|
||||
bus_class->get_fw_dev_path = virtio_bus_get_fw_dev_path;
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_bus_info = {
|
||||
|
@@ -1461,7 +1461,7 @@ static int virtio_rng_pci_init(VirtIOPCIProxy *vpci_dev)
|
||||
}
|
||||
|
||||
object_property_set_link(OBJECT(vrng),
|
||||
OBJECT(vrng->vdev.conf.default_backend), "rng",
|
||||
OBJECT(vrng->vdev.conf.rng), "rng",
|
||||
NULL);
|
||||
|
||||
return 0;
|
||||
|
@@ -374,9 +374,22 @@ static const MemoryRegionOps i6300esb_ops = {
|
||||
|
||||
static const VMStateDescription vmstate_i6300esb = {
|
||||
.name = "i6300esb_wdt",
|
||||
.version_id = sizeof(I6300State),
|
||||
.minimum_version_id = sizeof(I6300State),
|
||||
.minimum_version_id_old = sizeof(I6300State),
|
||||
/* With this VMSD's introduction, version_id/minimum_version_id were
|
||||
* erroneously set to sizeof(I6300State), causing a somewhat random
|
||||
* version_id to be set for every build. This eventually broke
|
||||
* migration.
|
||||
*
|
||||
* To correct this without breaking old->new migration for older versions
|
||||
* of QEMU, we've set version_id to a value high enough to exceed all past
|
||||
* values of sizeof(I6300State) across various build environments, and have
|
||||
* reset minimum_version_id_old/minimum_version_id to 1, since this VMSD
|
||||
* has never changed and thus can accept all past versions.
|
||||
*
|
||||
* For future changes we can treat these values as we normally would.
|
||||
*/
|
||||
.version_id = 10000,
|
||||
.minimum_version_id = 1,
|
||||
.minimum_version_id_old = 1,
|
||||
.fields = (VMStateField []) {
|
||||
VMSTATE_PCI_DEVICE(dev, I6300State),
|
||||
VMSTATE_INT32(reboot_enabled, I6300State),
|
||||
|
@@ -78,6 +78,9 @@ extern int fd_bootchk;
|
||||
void pc_register_ferr_irq(qemu_irq irq);
|
||||
void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
|
||||
|
||||
#define QEMU_BELOW_4G_RAM_END 0xe0000000
|
||||
#define QEMU_BELOW_4G_MMIO_LENGTH ((1ULL << 32) - QEMU_BELOW_4G_RAM_END)
|
||||
|
||||
void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge);
|
||||
void pc_hot_add_cpu(const int64_t id, Error **errp);
|
||||
void pc_acpi_init(const char *default_dsdt);
|
||||
|
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
int smbios_entry_add(const char *t);
|
||||
void smbios_add_field(int type, int offset, int len, void *data);
|
||||
void smbios_add_field(int type, int offset, const void *data, size_t len);
|
||||
uint8_t *smbios_get_table(size_t *length);
|
||||
|
||||
/*
|
||||
|
@@ -25,11 +25,7 @@ extern bool xen_allowed;
|
||||
|
||||
static inline bool xen_enabled(void)
|
||||
{
|
||||
#if defined(CONFIG_XEN_BACKEND) && defined(CONFIG_XEN)
|
||||
return xen_allowed;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
|
||||
|
@@ -42,18 +42,6 @@
|
||||
#include <signal.h>
|
||||
#include "glib-compat.h"
|
||||
|
||||
#if defined(__GLIBC__)
|
||||
# include <pty.h>
|
||||
#elif defined CONFIG_BSD
|
||||
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
|
||||
# include <libutil.h>
|
||||
# else
|
||||
# include <util.h>
|
||||
# endif
|
||||
#elif defined CONFIG_SOLARIS
|
||||
# include <stropts.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "sysemu/os-win32.h"
|
||||
#endif
|
||||
@@ -231,6 +219,8 @@ ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags)
|
||||
|
||||
#ifndef _WIN32
|
||||
int qemu_pipe(int pipefd[2]);
|
||||
/* like openpty() but also makes it raw; return master fd */
|
||||
int qemu_openpty_raw(int *aslave, char *pty_name);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#define QEMU_ERROR_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "qemu/compiler.h"
|
||||
|
||||
typedef struct Location {
|
||||
/* all members are private to qemu-error.c */
|
||||
|
@@ -2,6 +2,9 @@
|
||||
#define QEMU_LOG_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "qemu/compiler.h"
|
||||
#ifdef NEED_CPU_H
|
||||
#include "disas/disas.h"
|
||||
#endif
|
||||
|
@@ -70,12 +70,12 @@ struct CharDriverState {
|
||||
void (*chr_set_echo)(struct CharDriverState *chr, bool echo);
|
||||
void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open);
|
||||
void *opaque;
|
||||
int idle_tag;
|
||||
char *label;
|
||||
char *filename;
|
||||
int be_open;
|
||||
int fe_open;
|
||||
int explicit_fe_open;
|
||||
int explicit_be_open;
|
||||
int avail_connections;
|
||||
QemuOpts *opts;
|
||||
QTAILQ_ENTRY(CharDriverState) next;
|
||||
|
@@ -281,7 +281,7 @@ void monitor_flush(Monitor *mon)
|
||||
buf = qstring_get_str(mon->outbuf);
|
||||
len = qstring_get_length(mon->outbuf);
|
||||
|
||||
if (mon && len && !mon->mux_out) {
|
||||
if (len && !mon->mux_out) {
|
||||
rc = qemu_chr_fe_write(mon->chr, (const uint8_t *) buf, len);
|
||||
if (rc == len) {
|
||||
/* all flushed */
|
||||
|
18
net/tap.c
18
net/tap.c
@@ -698,9 +698,10 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
|
||||
if (tap->has_fd) {
|
||||
if (tap->has_ifname || tap->has_script || tap->has_downscript ||
|
||||
tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
|
||||
tap->has_fds) {
|
||||
tap->has_fds || tap->has_vhostfds) {
|
||||
error_report("ifname=, script=, downscript=, vnet_hdr=, "
|
||||
"helper=, queues=, and fds= are invalid with fd=");
|
||||
"helper=, queues=, fds=, and vhostfds= "
|
||||
"are invalid with fd=");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -725,9 +726,10 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
|
||||
|
||||
if (tap->has_ifname || tap->has_script || tap->has_downscript ||
|
||||
tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
|
||||
tap->has_fd) {
|
||||
tap->has_vhostfd) {
|
||||
error_report("ifname=, script=, downscript=, vnet_hdr=, "
|
||||
"helper=, queues=, and fd= are invalid with fds=");
|
||||
"helper=, queues=, and vhostfd= "
|
||||
"are invalid with fds=");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -765,9 +767,9 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
|
||||
}
|
||||
} else if (tap->has_helper) {
|
||||
if (tap->has_ifname || tap->has_script || tap->has_downscript ||
|
||||
tap->has_vnet_hdr || tap->has_queues || tap->has_fds) {
|
||||
tap->has_vnet_hdr || tap->has_queues || tap->has_vhostfds) {
|
||||
error_report("ifname=, script=, downscript=, and vnet_hdr= "
|
||||
"queues=, and fds= are invalid with helper=");
|
||||
"queues=, and vhostfds= are invalid with helper=");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -785,6 +787,10 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (tap->has_vhostfds) {
|
||||
error_report("vhostfds= is invalid if fds= wasn't specified");
|
||||
return -1;
|
||||
}
|
||||
script = tap->has_script ? tap->script : DEFAULT_NETWORK_SCRIPT;
|
||||
downscript = tap->has_downscript ? tap->downscript :
|
||||
DEFAULT_NETWORK_DOWN_SCRIPT;
|
||||
|
BIN
pc-bios/bios.bin
BIN
pc-bios/bios.bin
Binary file not shown.
118
qemu-char.c
118
qemu-char.c
@@ -110,19 +110,9 @@ void qemu_chr_be_event(CharDriverState *s, int event)
|
||||
s->chr_event(s->handler_opaque, event);
|
||||
}
|
||||
|
||||
static gboolean qemu_chr_be_generic_open_bh(gpointer opaque)
|
||||
{
|
||||
CharDriverState *s = opaque;
|
||||
qemu_chr_be_event(s, CHR_EVENT_OPENED);
|
||||
s->idle_tag = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void qemu_chr_be_generic_open(CharDriverState *s)
|
||||
{
|
||||
if (s->idle_tag == 0) {
|
||||
s->idle_tag = g_idle_add(qemu_chr_be_generic_open_bh, s);
|
||||
}
|
||||
qemu_chr_be_event(s, CHR_EVENT_OPENED);
|
||||
}
|
||||
|
||||
int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
|
||||
@@ -247,6 +237,7 @@ static CharDriverState *qemu_chr_open_null(void)
|
||||
|
||||
chr = g_malloc0(sizeof(CharDriverState));
|
||||
chr->chr_write = null_chr_write;
|
||||
chr->explicit_be_open = true;
|
||||
return chr;
|
||||
}
|
||||
|
||||
@@ -504,9 +495,6 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
|
||||
/* Frontend guest-open / -close notification is not support with muxes */
|
||||
chr->chr_set_fe_open = NULL;
|
||||
|
||||
/* Muxes are always open on creation */
|
||||
qemu_chr_be_generic_open(chr);
|
||||
|
||||
return chr;
|
||||
}
|
||||
|
||||
@@ -883,8 +871,6 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
|
||||
chr->chr_update_read_handler = fd_chr_update_read_handler;
|
||||
chr->chr_close = fd_chr_close;
|
||||
|
||||
qemu_chr_be_generic_open(chr);
|
||||
|
||||
return chr;
|
||||
}
|
||||
|
||||
@@ -980,63 +966,6 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
|
||||
return chr;
|
||||
}
|
||||
|
||||
#ifdef __sun__
|
||||
/* Once Solaris has openpty(), this is going to be removed. */
|
||||
static int openpty(int *amaster, int *aslave, char *name,
|
||||
struct termios *termp, struct winsize *winp)
|
||||
{
|
||||
const char *slave;
|
||||
int mfd = -1, sfd = -1;
|
||||
|
||||
*amaster = *aslave = -1;
|
||||
|
||||
mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
|
||||
if (mfd < 0)
|
||||
goto err;
|
||||
|
||||
if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
|
||||
goto err;
|
||||
|
||||
if ((slave = ptsname(mfd)) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
|
||||
goto err;
|
||||
|
||||
if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
|
||||
(termp != NULL && tcgetattr(sfd, termp) < 0))
|
||||
goto err;
|
||||
|
||||
if (amaster)
|
||||
*amaster = mfd;
|
||||
if (aslave)
|
||||
*aslave = sfd;
|
||||
if (winp)
|
||||
ioctl(sfd, TIOCSWINSZ, winp);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (sfd != -1)
|
||||
close(sfd);
|
||||
close(mfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void cfmakeraw (struct termios *termios_p)
|
||||
{
|
||||
termios_p->c_iflag &=
|
||||
~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
||||
termios_p->c_oflag &= ~OPOST;
|
||||
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||
termios_p->c_cflag &= ~(CSIZE|PARENB);
|
||||
termios_p->c_cflag |= CS8;
|
||||
|
||||
termios_p->c_cc[VMIN] = 0;
|
||||
termios_p->c_cc[VTIME] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
|
||||
|| defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
|
||||
|| defined(__GLIBC__)
|
||||
@@ -1208,34 +1137,24 @@ static CharDriverState *qemu_chr_open_pty(const char *id,
|
||||
{
|
||||
CharDriverState *chr;
|
||||
PtyCharDriver *s;
|
||||
struct termios tty;
|
||||
int master_fd, slave_fd;
|
||||
#if defined(__OpenBSD__) || defined(__DragonFly__)
|
||||
char pty_name[PATH_MAX];
|
||||
#define q_ptsname(x) pty_name
|
||||
#else
|
||||
char *pty_name = NULL;
|
||||
#define q_ptsname(x) ptsname(x)
|
||||
#endif
|
||||
|
||||
if (openpty(&master_fd, &slave_fd, pty_name, NULL, NULL) < 0) {
|
||||
master_fd = qemu_openpty_raw(&slave_fd, pty_name);
|
||||
if (master_fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set raw attributes on the pty. */
|
||||
tcgetattr(slave_fd, &tty);
|
||||
cfmakeraw(&tty);
|
||||
tcsetattr(slave_fd, TCSAFLUSH, &tty);
|
||||
close(slave_fd);
|
||||
|
||||
chr = g_malloc0(sizeof(CharDriverState));
|
||||
|
||||
chr->filename = g_strdup_printf("pty:%s", q_ptsname(master_fd));
|
||||
ret->pty = g_strdup(q_ptsname(master_fd));
|
||||
chr->filename = g_strdup_printf("pty:%s", pty_name);
|
||||
ret->pty = g_strdup(pty_name);
|
||||
ret->has_pty = true;
|
||||
|
||||
fprintf(stderr, "char device redirected to %s (label %s)\n",
|
||||
q_ptsname(master_fd), id);
|
||||
pty_name, id);
|
||||
|
||||
s = g_malloc0(sizeof(PtyCharDriver));
|
||||
chr->opaque = s;
|
||||
@@ -1243,6 +1162,7 @@ static CharDriverState *qemu_chr_open_pty(const char *id,
|
||||
chr->chr_update_read_handler = pty_chr_update_read_handler;
|
||||
chr->chr_close = pty_chr_close;
|
||||
chr->chr_add_watch = pty_chr_add_watch;
|
||||
chr->explicit_be_open = true;
|
||||
|
||||
s->fd = io_channel_from_fd(master_fd);
|
||||
s->timer_tag = 0;
|
||||
@@ -1595,8 +1515,6 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd)
|
||||
chr->chr_close = pp_close;
|
||||
chr->opaque = drv;
|
||||
|
||||
qemu_chr_be_generic_open(chr);
|
||||
|
||||
return chr;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
@@ -1650,6 +1568,7 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd)
|
||||
chr->opaque = (void *)(intptr_t)fd;
|
||||
chr->chr_write = null_chr_write;
|
||||
chr->chr_ioctl = pp_ioctl;
|
||||
chr->explicit_be_open = true;
|
||||
return chr;
|
||||
}
|
||||
#endif
|
||||
@@ -1880,7 +1799,6 @@ static CharDriverState *qemu_chr_open_win_path(const char *filename)
|
||||
g_free(chr);
|
||||
return NULL;
|
||||
}
|
||||
qemu_chr_be_generic_open(chr);
|
||||
return chr;
|
||||
}
|
||||
|
||||
@@ -1980,7 +1898,6 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
|
||||
g_free(chr);
|
||||
return NULL;
|
||||
}
|
||||
qemu_chr_be_generic_open(chr);
|
||||
return chr;
|
||||
}
|
||||
|
||||
@@ -1994,7 +1911,6 @@ static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
|
||||
s->hcom = fd_out;
|
||||
chr->opaque = s;
|
||||
chr->chr_write = win_chr_write;
|
||||
qemu_chr_be_generic_open(chr);
|
||||
return chr;
|
||||
}
|
||||
|
||||
@@ -2329,6 +2245,8 @@ static CharDriverState *qemu_chr_open_udp_fd(int fd)
|
||||
chr->chr_write = udp_chr_write;
|
||||
chr->chr_update_read_handler = udp_chr_update_read_handler;
|
||||
chr->chr_close = udp_chr_close;
|
||||
/* be isn't opened until we get a connection */
|
||||
chr->explicit_be_open = true;
|
||||
return chr;
|
||||
}
|
||||
|
||||
@@ -2731,6 +2649,8 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
|
||||
chr->get_msgfd = tcp_get_msgfd;
|
||||
chr->chr_add_client = tcp_chr_add_client;
|
||||
chr->chr_add_watch = tcp_chr_add_watch;
|
||||
/* be isn't opened until we get a connection */
|
||||
chr->explicit_be_open = true;
|
||||
|
||||
if (is_listen) {
|
||||
s->listen_fd = fd;
|
||||
@@ -3325,6 +3245,12 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
|
||||
if (!chr->filename)
|
||||
chr->filename = g_strdup(qemu_opt_get(opts, "backend"));
|
||||
chr->init = init;
|
||||
/* if we didn't create the chardev via qmp_chardev_add, we
|
||||
* need to send the OPENED event here
|
||||
*/
|
||||
if (!chr->explicit_be_open) {
|
||||
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
|
||||
}
|
||||
QTAILQ_INSERT_TAIL(&chardevs, chr, next);
|
||||
|
||||
if (qemu_opt_get_bool(opts, "mux", 0)) {
|
||||
@@ -3801,6 +3727,12 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
|
||||
chr->label = g_strdup(id);
|
||||
chr->avail_connections =
|
||||
(backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
|
||||
if (!chr->filename) {
|
||||
chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]);
|
||||
}
|
||||
if (!chr->explicit_be_open) {
|
||||
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
|
||||
}
|
||||
QTAILQ_INSERT_TAIL(&chardevs, chr, next);
|
||||
return ret;
|
||||
} else {
|
||||
|
@@ -1002,7 +1002,8 @@ int main(int argc, char **argv)
|
||||
case 's':
|
||||
service = optarg;
|
||||
if (strcmp(service, "install") == 0) {
|
||||
return ga_install_service(path, log_filepath);
|
||||
const char *fixed_state_dir;
|
||||
return ga_install_service(path, log_filepath, state_dir);
|
||||
} else if (strcmp(service, "uninstall") == 0) {
|
||||
return ga_uninstall_service();
|
||||
} else {
|
||||
|
@@ -29,58 +29,136 @@ static int printf_win_error(const char *text)
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(char *)&message, 0,
|
||||
NULL);
|
||||
n = printf("%s. (Error: %d) %s", text, (int)err, message);
|
||||
n = fprintf(stderr, "%s. (Error: %d) %s", text, (int)err, message);
|
||||
LocalFree(message);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int ga_install_service(const char *path, const char *logfile)
|
||||
/* Windows command line escaping. Based on
|
||||
* <http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx> and
|
||||
* <http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft%28v=vs.85%29.aspx>.
|
||||
*
|
||||
* The caller is responsible for initializing @buffer; prior contents are lost.
|
||||
*/
|
||||
static const char *win_escape_arg(const char *to_escape, GString *buffer)
|
||||
{
|
||||
size_t backslash_count;
|
||||
const char *c;
|
||||
|
||||
/* open with a double quote */
|
||||
g_string_assign(buffer, "\"");
|
||||
|
||||
backslash_count = 0;
|
||||
for (c = to_escape; *c != '\0'; ++c) {
|
||||
switch (*c) {
|
||||
case '\\':
|
||||
/* The meaning depends on the first non-backslash character coming
|
||||
* up.
|
||||
*/
|
||||
++backslash_count;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
/* We must escape each pending backslash, then escape the double
|
||||
* quote. This creates a case of "odd number of backslashes [...]
|
||||
* followed by a double quotation mark".
|
||||
*/
|
||||
while (backslash_count) {
|
||||
--backslash_count;
|
||||
g_string_append(buffer, "\\\\");
|
||||
}
|
||||
g_string_append(buffer, "\\\"");
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Any pending backslashes are without special meaning, flush them.
|
||||
* "Backslashes are interpreted literally, unless they immediately
|
||||
* precede a double quotation mark."
|
||||
*/
|
||||
while (backslash_count) {
|
||||
--backslash_count;
|
||||
g_string_append_c(buffer, '\\');
|
||||
}
|
||||
g_string_append_c(buffer, *c);
|
||||
}
|
||||
}
|
||||
|
||||
/* We're about to close with a double quote in string delimiter role.
|
||||
* Double all pending backslashes, creating a case of "even number of
|
||||
* backslashes [...] followed by a double quotation mark".
|
||||
*/
|
||||
while (backslash_count) {
|
||||
--backslash_count;
|
||||
g_string_append(buffer, "\\\\");
|
||||
}
|
||||
g_string_append_c(buffer, '"');
|
||||
|
||||
return buffer->str;
|
||||
}
|
||||
|
||||
int ga_install_service(const char *path, const char *logfile,
|
||||
const char *state_dir)
|
||||
{
|
||||
int ret = EXIT_FAILURE;
|
||||
SC_HANDLE manager;
|
||||
SC_HANDLE service;
|
||||
TCHAR cmdline[MAX_PATH];
|
||||
TCHAR module_fname[MAX_PATH];
|
||||
GString *esc;
|
||||
GString *cmdline;
|
||||
SERVICE_DESCRIPTION desc = { (char *)QGA_SERVICE_DESCRIPTION };
|
||||
|
||||
if (GetModuleFileName(NULL, cmdline, MAX_PATH) == 0) {
|
||||
if (GetModuleFileName(NULL, module_fname, MAX_PATH) == 0) {
|
||||
printf_win_error("No full path to service's executable");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
_snprintf(cmdline, MAX_PATH - strlen(cmdline), "%s -d", cmdline);
|
||||
esc = g_string_new("");
|
||||
cmdline = g_string_new("");
|
||||
|
||||
g_string_append_printf(cmdline, "%s -d",
|
||||
win_escape_arg(module_fname, esc));
|
||||
|
||||
if (path) {
|
||||
_snprintf(cmdline, MAX_PATH - strlen(cmdline), "%s -p %s", cmdline, path);
|
||||
g_string_append_printf(cmdline, " -p %s", win_escape_arg(path, esc));
|
||||
}
|
||||
if (logfile) {
|
||||
_snprintf(cmdline, MAX_PATH - strlen(cmdline), "%s -l %s -v",
|
||||
cmdline, logfile);
|
||||
g_string_append_printf(cmdline, " -l %s -v",
|
||||
win_escape_arg(logfile, esc));
|
||||
}
|
||||
if (state_dir) {
|
||||
g_string_append_printf(cmdline, " -t %s",
|
||||
win_escape_arg(state_dir, esc));
|
||||
}
|
||||
|
||||
g_debug("service's cmdline: %s", cmdline);
|
||||
g_debug("service's cmdline: %s", cmdline->str);
|
||||
|
||||
manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||
if (manager == NULL) {
|
||||
printf_win_error("No handle to service control manager");
|
||||
return EXIT_FAILURE;
|
||||
goto out_strings;
|
||||
}
|
||||
|
||||
service = CreateService(manager, QGA_SERVICE_NAME, QGA_SERVICE_DISPLAY_NAME,
|
||||
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,
|
||||
SERVICE_ERROR_NORMAL, cmdline, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (service) {
|
||||
SERVICE_DESCRIPTION desc = { (char *)QGA_SERVICE_DESCRIPTION };
|
||||
ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &desc);
|
||||
|
||||
printf("Service was installed successfully.\n");
|
||||
} else {
|
||||
SERVICE_ERROR_NORMAL, cmdline->str, NULL, NULL, NULL, NULL, NULL);
|
||||
if (service == NULL) {
|
||||
printf_win_error("Failed to install service");
|
||||
goto out_manager;
|
||||
}
|
||||
|
||||
ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &desc);
|
||||
fprintf(stderr, "Service was installed successfully.\n");
|
||||
ret = EXIT_SUCCESS;
|
||||
CloseServiceHandle(service);
|
||||
|
||||
out_manager:
|
||||
CloseServiceHandle(manager);
|
||||
|
||||
return (service == NULL);
|
||||
out_strings:
|
||||
g_string_free(cmdline, TRUE);
|
||||
g_string_free(esc, TRUE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ga_uninstall_service(void)
|
||||
@@ -104,7 +182,7 @@ int ga_uninstall_service(void)
|
||||
if (DeleteService(service) == FALSE) {
|
||||
printf_win_error("Failed to delete service");
|
||||
} else {
|
||||
printf("Service was deleted successfully.\n");
|
||||
fprintf(stderr, "Service was deleted successfully.\n");
|
||||
}
|
||||
|
||||
CloseServiceHandle(service);
|
||||
|
@@ -24,7 +24,8 @@ typedef struct GAService {
|
||||
SERVICE_STATUS_HANDLE status_handle;
|
||||
} GAService;
|
||||
|
||||
int ga_install_service(const char *path, const char *logfile);
|
||||
int ga_install_service(const char *path, const char *logfile,
|
||||
const char *state_dir);
|
||||
int ga_uninstall_service(void);
|
||||
|
||||
#endif
|
||||
|
@@ -442,7 +442,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
|
||||
int i;
|
||||
Object *inst;
|
||||
|
||||
for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
|
||||
for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
|
||||
if (obj->class->cast_cache[i] == typename) {
|
||||
goto out;
|
||||
}
|
||||
@@ -458,7 +458,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
|
||||
|
||||
assert(obj == inst);
|
||||
|
||||
if (obj == inst) {
|
||||
if (obj && obj == inst) {
|
||||
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
|
||||
obj->class->cast_cache[i - 1] = obj->class->cast_cache[i];
|
||||
}
|
||||
|
@@ -2,4 +2,4 @@
|
||||
config="$1"
|
||||
make -C seabios clean distclean
|
||||
cp "$config" seabios/.config
|
||||
make -C seabios olddefconfig
|
||||
make -C seabios oldnoconfig
|
||||
|
Submodule roms/seabios updated: 88cb66ea54...d4f7d90f47
8
savevm.c
8
savevm.c
@@ -322,13 +322,13 @@ QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
|
||||
FILE *stdio_file;
|
||||
QEMUFileStdio *s;
|
||||
|
||||
stdio_file = popen(command, mode);
|
||||
if (stdio_file == NULL) {
|
||||
if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
|
||||
fprintf(stderr, "qemu_popen: Argument validity check failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
|
||||
fprintf(stderr, "qemu_popen: Argument validity check failed\n");
|
||||
stdio_file = popen(command, mode);
|
||||
if (stdio_file == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@@ -255,6 +255,7 @@ static CharDriverState *chr_open(const char *subtype)
|
||||
chr->chr_add_watch = spice_chr_add_watch;
|
||||
chr->chr_close = spice_chr_close;
|
||||
chr->chr_set_fe_open = spice_chr_set_fe_open;
|
||||
chr->explicit_be_open = true;
|
||||
|
||||
QLIST_INSERT_HEAD(&spice_chars, s, next);
|
||||
|
||||
|
@@ -75,6 +75,8 @@ static void walk_pte2(MemoryMappingList *list,
|
||||
}
|
||||
|
||||
/* PAE Paging or IA-32e Paging */
|
||||
#define PLM4_ADDR_MASK 0xffffffffff000 /* selects bits 51:12 */
|
||||
|
||||
static void walk_pde(MemoryMappingList *list, hwaddr pde_start_addr,
|
||||
int32_t a20_mask, target_ulong start_line_addr)
|
||||
{
|
||||
@@ -105,7 +107,7 @@ static void walk_pde(MemoryMappingList *list, hwaddr pde_start_addr,
|
||||
continue;
|
||||
}
|
||||
|
||||
pte_start_addr = (pde & ~0xfff) & a20_mask;
|
||||
pte_start_addr = (pde & PLM4_ADDR_MASK) & a20_mask;
|
||||
walk_pte(list, pte_start_addr, a20_mask, line_addr);
|
||||
}
|
||||
}
|
||||
@@ -208,7 +210,7 @@ static void walk_pdpe(MemoryMappingList *list,
|
||||
continue;
|
||||
}
|
||||
|
||||
pde_start_addr = (pdpe & ~0xfff) & a20_mask;
|
||||
pde_start_addr = (pdpe & PLM4_ADDR_MASK) & a20_mask;
|
||||
walk_pde(list, pde_start_addr, a20_mask, line_addr);
|
||||
}
|
||||
}
|
||||
@@ -231,7 +233,7 @@ static void walk_pml4e(MemoryMappingList *list,
|
||||
}
|
||||
|
||||
line_addr = ((i & 0x1ffULL) << 39) | (0xffffULL << 48);
|
||||
pdpe_start_addr = (pml4e & ~0xfff) & a20_mask;
|
||||
pdpe_start_addr = (pml4e & PLM4_ADDR_MASK) & a20_mask;
|
||||
walk_pdpe(list, pdpe_start_addr, a20_mask, line_addr);
|
||||
}
|
||||
}
|
||||
@@ -249,7 +251,7 @@ int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
|
||||
if (env->hflags & HF_LMA_MASK) {
|
||||
hwaddr pml4e_addr;
|
||||
|
||||
pml4e_addr = (env->cr[3] & ~0xfff) & env->a20_mask;
|
||||
pml4e_addr = (env->cr[3] & PLM4_ADDR_MASK) & env->a20_mask;
|
||||
walk_pml4e(list, pml4e_addr, env->a20_mask);
|
||||
} else
|
||||
#endif
|
||||
|
@@ -221,7 +221,7 @@ X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
|
||||
|
||||
const char *get_register_name_32(unsigned int reg)
|
||||
{
|
||||
if (reg > CPU_NB_REGS32) {
|
||||
if (reg >= CPU_NB_REGS32) {
|
||||
return NULL;
|
||||
}
|
||||
return x86_reg_info_32[reg].name;
|
||||
|
@@ -4677,8 +4677,6 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
||||
}
|
||||
s->pc = pc_start;
|
||||
prefixes = 0;
|
||||
aflag = s->code32;
|
||||
dflag = s->code32;
|
||||
s->override = -1;
|
||||
rex_w = -1;
|
||||
rex_r = 0;
|
||||
@@ -4801,23 +4799,25 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
||||
}
|
||||
|
||||
/* Post-process prefixes. */
|
||||
if (prefixes & PREFIX_DATA) {
|
||||
dflag ^= 1;
|
||||
}
|
||||
if (prefixes & PREFIX_ADR) {
|
||||
aflag ^= 1;
|
||||
}
|
||||
#ifdef TARGET_X86_64
|
||||
if (CODE64(s)) {
|
||||
if (rex_w == 1) {
|
||||
/* 0x66 is ignored if rex.w is set */
|
||||
dflag = 2;
|
||||
/* In 64-bit mode, the default data size is 32-bit. Select 64-bit
|
||||
data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
|
||||
over 0x66 if both are present. */
|
||||
dflag = (rex_w > 0 ? 2 : prefixes & PREFIX_DATA ? 0 : 1);
|
||||
/* In 64-bit mode, 0x67 selects 32-bit addressing. */
|
||||
aflag = (prefixes & PREFIX_ADR ? 1 : 2);
|
||||
} else {
|
||||
/* In 16/32-bit mode, 0x66 selects the opposite data size. */
|
||||
dflag = s->code32;
|
||||
if (prefixes & PREFIX_DATA) {
|
||||
dflag ^= 1;
|
||||
}
|
||||
if (!(prefixes & PREFIX_ADR)) {
|
||||
aflag = 2;
|
||||
/* In 16/32-bit mode, 0x67 selects the opposite addressing. */
|
||||
aflag = s->code32;
|
||||
if (prefixes & PREFIX_ADR) {
|
||||
aflag ^= 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
s->prefix = prefixes;
|
||||
s->aflag = aflag;
|
||||
|
@@ -308,7 +308,8 @@ static int tcg_target_const_match (tcg_target_long val,
|
||||
|
||||
#define OPCD(opc) ((opc)<<26)
|
||||
#define XO19(opc) (OPCD(19)|((opc)<<1))
|
||||
#define XO30(opc) (OPCD(30)|((opc)<<2))
|
||||
#define MD30(opc) (OPCD(30)|((opc)<<2))
|
||||
#define MDS30(opc) (OPCD(30)|((opc)<<1))
|
||||
#define XO31(opc) (OPCD(31)|((opc)<<1))
|
||||
#define XO58(opc) (OPCD(58)|(opc))
|
||||
#define XO62(opc) (OPCD(62)|(opc))
|
||||
@@ -354,10 +355,10 @@ static int tcg_target_const_match (tcg_target_long val,
|
||||
#define RLWINM OPCD( 21)
|
||||
#define RLWNM OPCD( 23)
|
||||
|
||||
#define RLDICL XO30( 0)
|
||||
#define RLDICR XO30( 1)
|
||||
#define RLDIMI XO30( 3)
|
||||
#define RLDCL XO30( 8)
|
||||
#define RLDICL MD30( 0)
|
||||
#define RLDICR MD30( 1)
|
||||
#define RLDIMI MD30( 3)
|
||||
#define RLDCL MDS30( 8)
|
||||
|
||||
#define BCLR XO19( 16)
|
||||
#define BCCTR XO19(528)
|
||||
@@ -1661,7 +1662,7 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31);
|
||||
} else {
|
||||
tcg_out32(s, SUBFIC | TAI(0, args[2], 32));
|
||||
tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2])
|
||||
tcg_out32(s, RLWNM | SAB(args[1], args[0], 0)
|
||||
| MB(0) | ME(31));
|
||||
}
|
||||
break;
|
||||
@@ -1922,8 +1923,6 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
|
||||
if (a0 == 0) {
|
||||
tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
|
||||
/* Revert the source rotate that we performed above. */
|
||||
tcg_out_rld(s, RLDICL, a1, a1, 32, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1960,18 +1959,18 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
environment. So in 64-bit mode it's always carry-out of bit 63.
|
||||
The fallback code using deposit works just as well for 32-bit. */
|
||||
a0 = args[0], a1 = args[1];
|
||||
if (a0 == args[4] || (!const_args[5] && a0 == args[5])) {
|
||||
if (a0 == args[3] || (!const_args[5] && a0 == args[5])) {
|
||||
a0 = TCG_REG_R0;
|
||||
}
|
||||
if (const_args[3]) {
|
||||
tcg_out32(s, ADDIC | TAI(a0, args[2], args[3]));
|
||||
if (const_args[4]) {
|
||||
tcg_out32(s, ADDIC | TAI(a0, args[2], args[4]));
|
||||
} else {
|
||||
tcg_out32(s, ADDC | TAB(a0, args[2], args[3]));
|
||||
tcg_out32(s, ADDC | TAB(a0, args[2], args[4]));
|
||||
}
|
||||
if (const_args[5]) {
|
||||
tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[4]));
|
||||
tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3]));
|
||||
} else {
|
||||
tcg_out32(s, ADDE | TAB(a1, args[4], args[5]));
|
||||
tcg_out32(s, ADDE | TAB(a1, args[3], args[5]));
|
||||
}
|
||||
if (a0 != args[0]) {
|
||||
tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
|
||||
@@ -2149,7 +2148,7 @@ static const TCGTargetOpDef ppc_op_defs[] = {
|
||||
{ INDEX_op_deposit_i32, { "r", "0", "rZ" } },
|
||||
{ INDEX_op_deposit_i64, { "r", "0", "rZ" } },
|
||||
|
||||
{ INDEX_op_add2_i64, { "r", "r", "r", "rI", "r", "rZM" } },
|
||||
{ INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } },
|
||||
{ INDEX_op_sub2_i64, { "r", "r", "rI", "r", "rZM", "r" } },
|
||||
{ INDEX_op_muls2_i64, { "r", "r", "r", "r" } },
|
||||
{ INDEX_op_mulu2_i64, { "r", "r", "r", "r" } },
|
||||
|
@@ -1788,6 +1788,10 @@ static CharDriverState *text_console_init(ChardevVC *vc)
|
||||
s->chr = chr;
|
||||
chr->opaque = s;
|
||||
chr->chr_set_echo = text_console_set_echo;
|
||||
/* console/chardev init sometimes completes elsewhere in a 2nd
|
||||
* stage, so defer OPENED events until they are fully initialized
|
||||
*/
|
||||
chr->explicit_be_open = true;
|
||||
|
||||
if (display_state) {
|
||||
text_console_do_init(chr, display_state);
|
||||
|
14
ui/gtk.c
14
ui/gtk.c
@@ -1117,6 +1117,8 @@ static CharDriverState *gd_vc_handler(ChardevVC *unused)
|
||||
|
||||
chr = g_malloc0(sizeof(*chr));
|
||||
chr->chr_write = gd_vc_chr_write;
|
||||
/* defer OPENED events until our vc is fully initialized */
|
||||
chr->explicit_be_open = true;
|
||||
|
||||
vcs[nb_vcs++] = chr;
|
||||
|
||||
@@ -1156,8 +1158,7 @@ static GSList *gd_vc_init(GtkDisplayState *s, VirtualConsole *vc, int index, GSL
|
||||
GIOChannel *chan;
|
||||
GtkWidget *scrolled_window;
|
||||
GtkAdjustment *vadjustment;
|
||||
int master_fd, slave_fd, ret;
|
||||
struct termios tty;
|
||||
int master_fd, slave_fd;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "vc%d", index);
|
||||
snprintf(path, sizeof(path), "<QEMU>/View/VC%d", index);
|
||||
@@ -1177,13 +1178,8 @@ static GSList *gd_vc_init(GtkDisplayState *s, VirtualConsole *vc, int index, GSL
|
||||
|
||||
vc->terminal = vte_terminal_new();
|
||||
|
||||
ret = openpty(&master_fd, &slave_fd, NULL, NULL, NULL);
|
||||
g_assert(ret != -1);
|
||||
|
||||
/* Set raw attributes on the pty. */
|
||||
tcgetattr(slave_fd, &tty);
|
||||
cfmakeraw(&tty);
|
||||
tcsetattr(slave_fd, TCSAFLUSH, &tty);
|
||||
master_fd = qemu_openpty_raw(&slave_fd, NULL);
|
||||
g_assert(master_fd != -1);
|
||||
|
||||
#if VTE_CHECK_VERSION(0, 26, 0)
|
||||
pty = vte_pty_new_foreign(master_fd, NULL);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
util-obj-y = osdep.o cutils.o unicode.o qemu-timer-common.o
|
||||
util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o event_notifier-win32.o
|
||||
util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o event_notifier-posix.o
|
||||
util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o event_notifier-posix.o qemu-openpty.o
|
||||
util-obj-y += envlist.o path.o host-utils.o cache-utils.o module.o
|
||||
util-obj-y += bitmap.o bitops.o hbitmap.o
|
||||
util-obj-y += fifo8.o
|
||||
|
135
util/qemu-openpty.c
Normal file
135
util/qemu-openpty.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* qemu-openpty.c
|
||||
*
|
||||
* Copyright (c) 2003-2008 Fabrice Bellard
|
||||
* Copyright (c) 2010 Red Hat, Inc.
|
||||
*
|
||||
* Wrapper function qemu_openpty() implementation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is not part of oslib-posix.c because this function
|
||||
* uses openpty() which often in -lutil, and if we add this
|
||||
* dependency to oslib-posix.o, every app will have to be
|
||||
* linked with -lutil.
|
||||
*/
|
||||
|
||||
#include "config-host.h"
|
||||
#include "qemu-common.h"
|
||||
|
||||
#if defined(__GLIBC__)
|
||||
# include <pty.h>
|
||||
#elif defined CONFIG_BSD
|
||||
# include <termios.h>
|
||||
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
|
||||
# include <libutil.h>
|
||||
# else
|
||||
# include <util.h>
|
||||
# endif
|
||||
#elif defined CONFIG_SOLARIS
|
||||
# include <termios.h>
|
||||
# include <stropts.h>
|
||||
#endif
|
||||
|
||||
#ifdef __sun__
|
||||
/* Once Solaris has openpty(), this is going to be removed. */
|
||||
static int openpty(int *amaster, int *aslave, char *name,
|
||||
struct termios *termp, struct winsize *winp)
|
||||
{
|
||||
const char *slave;
|
||||
int mfd = -1, sfd = -1;
|
||||
|
||||
*amaster = *aslave = -1;
|
||||
|
||||
mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
|
||||
if (mfd < 0)
|
||||
goto err;
|
||||
|
||||
if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
|
||||
goto err;
|
||||
|
||||
if ((slave = ptsname(mfd)) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
|
||||
goto err;
|
||||
|
||||
if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
|
||||
(termp != NULL && tcgetattr(sfd, termp) < 0))
|
||||
goto err;
|
||||
|
||||
if (amaster)
|
||||
*amaster = mfd;
|
||||
if (aslave)
|
||||
*aslave = sfd;
|
||||
if (winp)
|
||||
ioctl(sfd, TIOCSWINSZ, winp);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (sfd != -1)
|
||||
close(sfd);
|
||||
close(mfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void cfmakeraw (struct termios *termios_p)
|
||||
{
|
||||
termios_p->c_iflag &=
|
||||
~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
||||
termios_p->c_oflag &= ~OPOST;
|
||||
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||
termios_p->c_cflag &= ~(CSIZE|PARENB);
|
||||
termios_p->c_cflag |= CS8;
|
||||
|
||||
termios_p->c_cc[VMIN] = 0;
|
||||
termios_p->c_cc[VTIME] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int qemu_openpty_raw(int *aslave, char *pty_name)
|
||||
{
|
||||
int amaster;
|
||||
struct termios tty;
|
||||
#if defined(__OpenBSD__) || defined(__DragonFly__)
|
||||
char pty_buf[PATH_MAX];
|
||||
#define q_ptsname(x) pty_buf
|
||||
#else
|
||||
char *pty_buf = NULL;
|
||||
#define q_ptsname(x) ptsname(x)
|
||||
#endif
|
||||
|
||||
if (openpty(&amaster, aslave, pty_buf, NULL, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set raw attributes on the pty. */
|
||||
tcgetattr(*aslave, &tty);
|
||||
cfmakeraw(&tty);
|
||||
tcsetattr(*aslave, TCSAFLUSH, &tty);
|
||||
|
||||
if (pty_name) {
|
||||
strcpy(pty_name, q_ptsname(amaster));
|
||||
}
|
||||
|
||||
return amaster;
|
||||
}
|
@@ -24,7 +24,6 @@
|
||||
|
||||
#include "monitor/monitor.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "qemu-common.h" /* for qemu_isdigit */
|
||||
#include "qemu/main-loop.h"
|
||||
|
||||
#ifndef AI_ADDRCONFIG
|
||||
@@ -511,19 +510,15 @@ InetSocketAddress *inet_parse(const char *str, Error **errp)
|
||||
goto fail;
|
||||
}
|
||||
addr->ipv6 = addr->has_ipv6 = true;
|
||||
} else if (qemu_isdigit(str[0])) {
|
||||
/* IPv4 addr */
|
||||
if (2 != sscanf(str, "%64[0-9.]:%32[^,]%n", host, port, &pos)) {
|
||||
error_setg(errp, "error parsing IPv4 address '%s'", str);
|
||||
goto fail;
|
||||
}
|
||||
addr->ipv4 = addr->has_ipv4 = true;
|
||||
} else {
|
||||
/* hostname */
|
||||
/* hostname or IPv4 addr */
|
||||
if (2 != sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos)) {
|
||||
error_setg(errp, "error parsing address '%s'", str);
|
||||
goto fail;
|
||||
}
|
||||
if (host[strspn(host, "0123456789.")] == '\0') {
|
||||
addr->ipv4 = addr->has_ipv4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
addr->host = g_strdup(host);
|
||||
|
2
vl.c
2
vl.c
@@ -2022,7 +2022,7 @@ static void main_loop(void)
|
||||
int64_t ti;
|
||||
#endif
|
||||
do {
|
||||
nonblocking = !kvm_enabled() && last_io > 0;
|
||||
nonblocking = !kvm_enabled() && !xen_enabled() && last_io > 0;
|
||||
#ifdef CONFIG_PROFILER
|
||||
ti = profile_getclock();
|
||||
#endif
|
||||
|
12
xen-all.c
12
xen-all.c
@@ -161,18 +161,18 @@ static void xen_ram_init(ram_addr_t ram_size)
|
||||
ram_addr_t block_len;
|
||||
|
||||
block_len = ram_size;
|
||||
if (ram_size >= HVM_BELOW_4G_RAM_END) {
|
||||
if (ram_size >= QEMU_BELOW_4G_RAM_END) {
|
||||
/* Xen does not allocate the memory continuously, and keep a hole at
|
||||
* HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH
|
||||
* QEMU_BELOW_4G_RAM_END of QEMU_BELOW_4G_MMIO_LENGTH
|
||||
*/
|
||||
block_len += HVM_BELOW_4G_MMIO_LENGTH;
|
||||
block_len += QEMU_BELOW_4G_MMIO_LENGTH;
|
||||
}
|
||||
memory_region_init_ram(&ram_memory, "xen.ram", block_len);
|
||||
vmstate_register_ram_global(&ram_memory);
|
||||
|
||||
if (ram_size >= HVM_BELOW_4G_RAM_END) {
|
||||
above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END;
|
||||
below_4g_mem_size = HVM_BELOW_4G_RAM_END;
|
||||
if (ram_size >= QEMU_BELOW_4G_RAM_END) {
|
||||
above_4g_mem_size = ram_size - QEMU_BELOW_4G_RAM_END;
|
||||
below_4g_mem_size = QEMU_BELOW_4G_RAM_END;
|
||||
} else {
|
||||
below_4g_mem_size = ram_size;
|
||||
}
|
||||
|
Reference in New Issue
Block a user