IscsiLun *iscsilun;
QEMUTimer retry_timer;
bool force_next_flush;
+ int err_code;
} IscsiTask;
typedef struct IscsiAIOCB {
return -mean * log((double)rand() / RAND_MAX);
}
-/* SCSI_STATUS_TASK_SET_FULL and SCSI_STATUS_TIMEOUT were introduced
- * in libiscsi 1.10.0 as part of an enum. The LIBISCSI_API_VERSION
- * macro was introduced in 1.11.0. So use the API_VERSION macro as
- * a hint that the macros are defined and define them ourselves
- * otherwise to keep the required libiscsi version at 1.9.0 */
-#if !defined(LIBISCSI_API_VERSION)
-#define QEMU_SCSI_STATUS_TASK_SET_FULL 0x28
-#define QEMU_SCSI_STATUS_TIMEOUT 0x0f000002
-#else
-#define QEMU_SCSI_STATUS_TASK_SET_FULL SCSI_STATUS_TASK_SET_FULL
-#define QEMU_SCSI_STATUS_TIMEOUT SCSI_STATUS_TIMEOUT
+/* SCSI_SENSE_ASCQ_INVALID_FIELD_IN_PARAMETER_LIST was introduced in
+ * libiscsi 1.10.0, together with other constants we need. Use it as
+ * a hint that we have to define them ourselves if needed, to keep the
+ * minimum required libiscsi version at 1.9.0. We use an ASCQ macro for
+ * the test because SCSI_STATUS_* is an enum.
+ *
+ * To guard against future changes where SCSI_SENSE_ASCQ_* also becomes
+ * an enum, check against the LIBISCSI_API_VERSION macro, which was
+ * introduced in 1.11.0. If it is present, there is no need to define
+ * anything.
+ */
+#if !defined(SCSI_SENSE_ASCQ_INVALID_FIELD_IN_PARAMETER_LIST) && \
+ !defined(LIBISCSI_API_VERSION)
+#define SCSI_STATUS_TASK_SET_FULL 0x28
+#define SCSI_STATUS_TIMEOUT 0x0f000002
+#define SCSI_SENSE_ASCQ_INVALID_FIELD_IN_PARAMETER_LIST 0x2600
+#define SCSI_SENSE_ASCQ_PARAMETER_LIST_LENGTH_ERROR 0x1a00
#endif
+static int iscsi_translate_sense(struct scsi_sense *sense)
+{
+ int ret;
+
+ switch (sense->key) {
+ case SCSI_SENSE_NOT_READY:
+ return -EBUSY;
+ case SCSI_SENSE_DATA_PROTECTION:
+ return -EACCES;
+ case SCSI_SENSE_COMMAND_ABORTED:
+ return -ECANCELED;
+ case SCSI_SENSE_ILLEGAL_REQUEST:
+ /* Parse ASCQ */
+ break;
+ default:
+ return -EIO;
+ }
+ switch (sense->ascq) {
+ case SCSI_SENSE_ASCQ_PARAMETER_LIST_LENGTH_ERROR:
+ case SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE:
+ case SCSI_SENSE_ASCQ_INVALID_FIELD_IN_CDB:
+ case SCSI_SENSE_ASCQ_INVALID_FIELD_IN_PARAMETER_LIST:
+ ret = -EINVAL;
+ break;
+ case SCSI_SENSE_ASCQ_LBA_OUT_OF_RANGE:
+ ret = -ENOSPC;
+ break;
+ case SCSI_SENSE_ASCQ_LOGICAL_UNIT_NOT_SUPPORTED:
+ ret = -ENOTSUP;
+ break;
+ case SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT:
+ case SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED:
+ case SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN:
+ ret = -ENOMEDIUM;
+ break;
+ case SCSI_SENSE_ASCQ_WRITE_PROTECTED:
+ ret = -EACCES;
+ break;
+ default:
+ ret = -EIO;
+ break;
+ }
+ return ret;
+}
+
static void
iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
void *command_data, void *opaque)
goto out;
}
if (status == SCSI_STATUS_BUSY ||
- status == QEMU_SCSI_STATUS_TIMEOUT ||
- status == QEMU_SCSI_STATUS_TASK_SET_FULL) {
+ status == SCSI_STATUS_TIMEOUT ||
+ status == SCSI_STATUS_TASK_SET_FULL) {
unsigned retry_time =
exp_random(iscsi_retry_times[iTask->retries - 1]);
- if (status == QEMU_SCSI_STATUS_TIMEOUT) {
+ if (status == SCSI_STATUS_TIMEOUT) {
/* make sure the request is rescheduled AFTER the
* reconnect is initiated */
retry_time = EVENT_INTERVAL * 2;
return;
}
}
+ iTask->err_code = iscsi_translate_sense(&task->sense);
error_report("iSCSI Failure: %s", iscsi_get_error(iscsi));
} else {
iTask->iscsilun->force_next_flush |= iTask->force_next_flush;
}
if (iTask.status != SCSI_STATUS_GOOD) {
- return -EIO;
+ return iTask.err_code;
}
iscsi_allocationmap_set(iscsilun, sector_num, nb_sectors);
}
if (iTask.status != SCSI_STATUS_GOOD) {
- return -EIO;
+ return iTask.err_code;
}
return 0;
}
if (iTask.status != SCSI_STATUS_GOOD) {
- return -EIO;
+ return iTask.err_code;
}
return 0;
if (status < 0) {
error_report("Failed to ioctl(SG_IO) to iSCSI lun. %s",
iscsi_get_error(iscsi));
- acb->status = -EIO;
+ acb->status = iscsi_translate_sense(&acb->task->sense);
}
acb->ioh->driver_status = 0;
}
if (iTask.status != SCSI_STATUS_GOOD) {
- return -EIO;
+ return iTask.err_code;
}
iscsi_allocationmap_clear(iscsilun, sector_num, nb_sectors);
}
if (iTask.status != SCSI_STATUS_GOOD) {
- return -EIO;
+ return iTask.err_code;
}
if (flags & BDRV_REQ_MAY_UNMAP) {
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS
+# Don't allow CCACHE, if present, to use cached results of compile tests!
+export CCACHE_RECACHE=yes
+
# Temporary directory used for files created while
# configure runs. Since it is in the build directory
# we can safely blow away any previous version of it
gprof="no"
debug_tcg="no"
debug="no"
+fortify_source=""
strip_opt="yes"
tcg_interpreter="no"
bigendian="no"
--enable-modules)
modules="yes"
;;
+ --disable-modules)
+ modules="no"
+ ;;
--cpu=*)
;;
--target-list=*) target_list="$optarg"
debug_tcg="yes"
debug="yes"
strip_opt="no"
+ fortify_source="no"
;;
--enable-sparse) sparse="yes"
;;
# check if ccache is interfering with
# semantic analysis of macros
+unset CCACHE_CPP2
ccache_cpp2=no
cat > $TMPC << EOF
static const int Z = 1;
ccache_cpp2=yes
fi
+#################################################
+# clang does not support glibc + FORTIFY_SOURCE.
+
+if test "$fortify_source" != "no"; then
+ if echo | $cc -dM -E - | grep __clang__ > /dev/null 2>&1 ; then
+ fortify_source="no";
+ elif echo | $cxx -dM -E - | grep __clang__ > /dev/null 2>&1 ; then
+ fortify_source="no";
+ else
+ fortify_source="yes"
+ fi
+fi
+
##########################################
# End of CC checks
# After here, no more $cc or $ld runs
if test "$gcov" = "yes" ; then
CFLAGS="-fprofile-arcs -ftest-coverage -g $CFLAGS"
LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS"
-elif test "$debug" = "no" ; then
+elif test "$fortify_source" = "yes" ; then
CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS"
fi
only be set by a memory fault) */
} /* for(;;) */
} else {
- /* Reload env after longjmp - the compiler may have smashed all
- * local variables as longjmp is marked 'noreturn'. */
+#if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)
+ /* Some compilers wrongly smash all local variables after
+ * siglongjmp. There were bug reports for gcc 4.5.0 and clang.
+ * Reload essential local variables here for those compilers.
+ * Newer versions of gcc would complain about this code (-Wclobbered). */
cpu = current_cpu;
cc = CPU_GET_CLASS(cpu);
- cpu->can_do_io = 1;
#ifdef TARGET_I386
x86_cpu = X86_CPU(cpu);
env = &x86_cpu->env;
#endif
+#else /* buggy compiler */
+ /* Assert that the compiler does not smash local variables. */
+ g_assert(cpu == current_cpu);
+ g_assert(cc == CPU_GET_CLASS(cpu));
+#ifdef TARGET_I386
+ g_assert(x86_cpu == X86_CPU(cpu));
+ g_assert(env == &x86_cpu->env);
+#endif
+#endif /* buggy compiler */
+ cpu->can_do_io = 1;
tb_lock_reset();
}
} /* for(;;) */
}
}
-void cpu_clean_all_dirty(void)
-{
- CPUState *cpu;
-
- CPU_FOREACH(cpu) {
- cpu_clean_state(cpu);
- }
-}
-
static int do_vm_stop(RunState state)
{
int ret = 0;
const char *path,
Error **errp)
{
+ struct stat st;
char *filename;
char *sanitized_name;
char *c;
goto error;
}
- /* Make name safe to use with mkstemp by replacing '/' with '_'. */
- sanitized_name = g_strdup(memory_region_name(block->mr));
- for (c = sanitized_name; *c != '\0'; c++) {
- if (*c == '/')
- *c = '_';
- }
+ if (!stat(path, &st) && S_ISDIR(st.st_mode)) {
+ /* Make name safe to use with mkstemp by replacing '/' with '_'. */
+ sanitized_name = g_strdup(memory_region_name(block->mr));
+ for (c = sanitized_name; *c != '\0'; c++) {
+ if (*c == '/') {
+ *c = '_';
+ }
+ }
- filename = g_strdup_printf("%s/qemu_back_mem.%s.XXXXXX", path,
- sanitized_name);
- g_free(sanitized_name);
+ filename = g_strdup_printf("%s/qemu_back_mem.%s.XXXXXX", path,
+ sanitized_name);
+ g_free(sanitized_name);
+
+ fd = mkstemp(filename);
+ if (fd >= 0) {
+ unlink(filename);
+ }
+ g_free(filename);
+ } else {
+ fd = open(path, O_RDWR | O_CREAT, 0644);
+ }
- fd = mkstemp(filename);
if (fd < 0) {
error_setg_errno(errp, errno,
"unable to create backing store for hugepages");
- g_free(filename);
goto error;
}
- unlink(filename);
- g_free(filename);
memory = ROUND_UP(memory, hpagesize);
return area;
error:
- if (mem_prealloc) {
- error_report("%s", error_get_pretty(*errp));
- exit(1);
- }
return NULL;
}
#endif
void cpu_exec_init_all(void)
{
qemu_mutex_init(&ram_list.mutex);
- memory_map_init();
io_mem_init();
+ memory_map_init();
qemu_mutex_init(&map_client_list_lock);
}
strcpy((void *) w, "hw-build"); /* char component[12] */
w += 6;
strcpy((void *) w, "QEMU ");
- pstrcat((void *) w, 12, qemu_get_version()); /* char version[12] */
+ pstrcat((void *) w, 12, qemu_hw_version()); /* char version[12] */
w += 6;
tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
#include "qemu/host-utils.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
-#include "sysemu/cpus.h"
+#include "kvm_i386.h"
#include "hw/sysbus.h"
#include "hw/kvm/clock.h"
return;
}
- cpu_synchronize_all_states();
- /* In theory, the cpu_synchronize_all_states() call above wouldn't
- * affect the rest of the code, as the VCPU state inside CPUState
- * is supposed to always match the VCPU state on the kernel side.
- *
- * In practice, calling cpu_synchronize_state() too soon will load the
- * kernel-side APIC state into X86CPU.apic_state too early, APIC state
- * won't be reloaded later because CPUState.vcpu_dirty==true, and
- * outdated APIC state may be migrated to another host.
- *
- * The real fix would be to make sure outdated APIC state is read
- * from the kernel again when necessary. While this is not fixed, we
- * need the cpu_clean_all_dirty() call below.
- */
- cpu_clean_all_dirty();
+ kvm_synchronize_all_tsc();
ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
if (ret < 0) {
static void pc_i440fx_2_5_machine_options(MachineClass *m)
{
pc_i440fx_machine_options(m);
+ m->hw_version = QEMU_VERSION;
m->alias = "pc";
m->is_default = 1;
}
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_i440fx_2_5_machine_options(m);
+ m->hw_version = "2.4.0";
m->alias = NULL;
m->is_default = 0;
pcmc->broken_reserved_end = true;
static void pc_i440fx_2_3_machine_options(MachineClass *m)
{
pc_i440fx_2_4_machine_options(m);
+ m->hw_version = "2.3.0";
m->alias = NULL;
m->is_default = 0;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_3);
static void pc_i440fx_2_2_machine_options(MachineClass *m)
{
pc_i440fx_2_3_machine_options(m);
+ m->hw_version = "2.2.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_2_2);
}
static void pc_i440fx_2_1_machine_options(MachineClass *m)
{
pc_i440fx_2_2_machine_options(m);
+ m->hw_version = "2.1.0";
m->default_display = NULL;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_1);
}
static void pc_i440fx_2_0_machine_options(MachineClass *m)
{
pc_i440fx_2_1_machine_options(m);
+ m->hw_version = "2.0.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_2_0);
}
static void pc_i440fx_1_7_machine_options(MachineClass *m)
{
pc_i440fx_2_0_machine_options(m);
+ m->hw_version = "1.7.0";
m->default_machine_opts = NULL;
SET_MACHINE_COMPAT(m, PC_COMPAT_1_7);
}
static void pc_i440fx_1_6_machine_options(MachineClass *m)
{
pc_i440fx_1_7_machine_options(m);
+ m->hw_version = "1.6.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_1_6);
}
static void pc_i440fx_1_5_machine_options(MachineClass *m)
{
pc_i440fx_1_6_machine_options(m);
+ m->hw_version = "1.5.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_1_5);
}
static void pc_i440fx_1_4_machine_options(MachineClass *m)
{
pc_i440fx_1_5_machine_options(m);
+ m->hw_version = "1.4.0";
m->hot_add_cpu = NULL;
SET_MACHINE_COMPAT(m, PC_COMPAT_1_4);
}
static void pc_i440fx_1_3_machine_options(MachineClass *m)
{
pc_i440fx_1_4_machine_options(m);
+ m->hw_version = "1.3.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_1_3);
}
static void pc_i440fx_1_2_machine_options(MachineClass *m)
{
pc_i440fx_1_3_machine_options(m);
+ m->hw_version = "1.2.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_1_2);
}
static void pc_i440fx_1_1_machine_options(MachineClass *m)
{
pc_i440fx_1_2_machine_options(m);
+ m->hw_version = "1.1.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_1_1);
}
static void pc_q35_2_5_machine_options(MachineClass *m)
{
pc_q35_machine_options(m);
+ m->hw_version = QEMU_VERSION;
m->alias = "q35";
}
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_q35_2_5_machine_options(m);
+ m->hw_version = "2.4.0";
m->alias = NULL;
pcmc->broken_reserved_end = true;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_4);
static void pc_q35_2_3_machine_options(MachineClass *m)
{
pc_q35_2_4_machine_options(m);
+ m->hw_version = "2.3.0";
m->no_floppy = 0;
m->no_tco = 1;
m->alias = NULL;
static void pc_q35_2_2_machine_options(MachineClass *m)
{
pc_q35_2_3_machine_options(m);
+ m->hw_version = "2.2.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_2_2);
}
static void pc_q35_2_1_machine_options(MachineClass *m)
{
pc_q35_2_2_machine_options(m);
+ m->hw_version = "2.1.0";
m->default_display = NULL;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_1);
}
static void pc_q35_2_0_machine_options(MachineClass *m)
{
pc_q35_2_1_machine_options(m);
+ m->hw_version = "2.0.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_2_0);
}
static void pc_q35_1_7_machine_options(MachineClass *m)
{
pc_q35_2_0_machine_options(m);
+ m->hw_version = "1.7.0";
m->default_machine_opts = NULL;
SET_MACHINE_COMPAT(m, PC_COMPAT_1_7);
}
static void pc_q35_1_6_machine_options(MachineClass *m)
{
pc_q35_machine_options(m);
+ m->hw_version = "1.6.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_1_6);
}
static void pc_q35_1_5_machine_options(MachineClass *m)
{
pc_q35_1_6_machine_options(m);
+ m->hw_version = "1.5.0";
SET_MACHINE_COMPAT(m, PC_COMPAT_1_5);
}
static void pc_q35_1_4_machine_options(MachineClass *m)
{
pc_q35_1_5_machine_options(m);
+ m->hw_version = "1.4.0";
m->hot_add_cpu = NULL;
SET_MACHINE_COMPAT(m, PC_COMPAT_1_4);
}
if (version) {
pstrcpy(s->version, sizeof(s->version), version);
} else {
- pstrcpy(s->version, sizeof(s->version), qemu_get_version());
+ pstrcpy(s->version, sizeof(s->version), qemu_hw_version());
}
ide_reset(s);
memcpy(info.product_name, base_class->product_name, 24);
snprintf(info.serial_number, 32, "%s", s->hba_serial);
- snprintf(info.package_version, 0x60, "%s-QEMU", QEMU_VERSION);
+ snprintf(info.package_version, 0x60, "%s-QEMU", qemu_hw_version());
memcpy(info.image_component[0].name, "APP", 3);
snprintf(info.image_component[0].version, 10, "%s-QEMU",
base_class->product_version);
r->buf[7] = 0x10 | (r->req.bus->info->tcq ? 0x02 : 0); /* Sync, TCQ. */
memcpy(&r->buf[8], "QEMU ", 8);
memcpy(&r->buf[16], "QEMU TARGET ", 16);
- pstrcpy((char *) &r->buf[32], 4, qemu_get_version());
+ pstrcpy((char *) &r->buf[32], 4, qemu_hw_version());
}
return true;
}
}
if (!s->version) {
- s->version = g_strdup(qemu_get_version());
+ s->version = g_strdup(qemu_hw_version());
}
if (!s->vendor) {
s->vendor = g_strdup("QEMU");
.driver = "host" "-" TYPE_X86_CPU,\
.property = "host-cache-info",\
.value = "on",\
+ },\
+ {\
+ .driver = TYPE_X86_CPU,\
+ .property = "check",\
+ .value = "off",\
+ },\
+ {\
+ .driver = "qemu64" "-" TYPE_X86_CPU,\
+ .property = "sse4a",\
+ .value = "on",\
+ },\
+ {\
+ .driver = "qemu64" "-" TYPE_X86_CPU,\
+ .property = "abm",\
+ .value = "on",\
+ },\
+ {\
+ .driver = "qemu64" "-" TYPE_X86_CPU,\
+ .property = "popcnt",\
+ .value = "on",\
+ },\
+ {\
+ .driver = "qemu32" "-" TYPE_X86_CPU,\
+ .property = "popcnt",\
+ .value = "on",\
},
#define PC_COMPAT_2_3 \
#define CPU_LOG_INT (1 << 4)
#define CPU_LOG_EXEC (1 << 5)
#define CPU_LOG_PCALL (1 << 6)
-#define CPU_LOG_IOPORT (1 << 7)
#define CPU_LOG_TB_CPU (1 << 8)
#define CPU_LOG_RESET (1 << 9)
#define LOG_UNIMP (1 << 10)
void qemu_set_cloexec(int fd);
-void qemu_set_version(const char *);
-const char *qemu_get_version(void);
+void qemu_set_hw_version(const char *);
+const char *qemu_hw_version(void);
void fips_set_state(bool requested);
bool fips_get_state(void);
void cpu_synchronize_all_states(void);
void cpu_synchronize_all_post_reset(void);
void cpu_synchronize_all_post_init(void);
-void cpu_clean_all_dirty(void);
void qtest_clock_warp(int64_t dest);
void kvm_cpu_synchronize_state(CPUState *cpu);
void kvm_cpu_synchronize_post_reset(CPUState *cpu);
void kvm_cpu_synchronize_post_init(CPUState *cpu);
-void kvm_cpu_clean_state(CPUState *cpu);
/* generic hooks - to be moved/refactored once there are more users */
}
}
-static inline void cpu_clean_state(CPUState *cpu)
-{
- if (kvm_enabled()) {
- kvm_cpu_clean_state(cpu);
- }
-}
-
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev);
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
PCIDevice *dev);
#include "exec/memory.h"
#include "exec/address-spaces.h"
-//#define DEBUG_IOPORT
-
-#ifdef DEBUG_IOPORT
-# define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)
-#else
-# define LOG_IOPORT(...) do { } while (0)
-#endif
-
typedef struct MemoryRegionPortioList {
MemoryRegion mr;
void *portio_opaque;
void cpu_outb(pio_addr_t addr, uint8_t val)
{
- LOG_IOPORT("outb: %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
- trace_cpu_out(addr, val);
+ trace_cpu_out(addr, 'b', val);
address_space_write(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED,
&val, 1);
}
{
uint8_t buf[2];
- LOG_IOPORT("outw: %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
- trace_cpu_out(addr, val);
+ trace_cpu_out(addr, 'w', val);
stw_p(buf, val);
address_space_write(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED,
buf, 2);
{
uint8_t buf[4];
- LOG_IOPORT("outl: %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
- trace_cpu_out(addr, val);
+ trace_cpu_out(addr, 'l', val);
stl_p(buf, val);
address_space_write(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED,
buf, 4);
address_space_read(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED,
&val, 1);
- trace_cpu_in(addr, val);
- LOG_IOPORT("inb : %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
+ trace_cpu_in(addr, 'b', val);
return val;
}
address_space_read(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED, buf, 2);
val = lduw_p(buf);
- trace_cpu_in(addr, val);
- LOG_IOPORT("inw : %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
+ trace_cpu_in(addr, 'w', val);
return val;
}
address_space_read(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED, buf, 4);
val = ldl_p(buf);
- trace_cpu_in(addr, val);
- LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
+ trace_cpu_in(addr, 'l', val);
return val;
}
run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, cpu);
}
-void kvm_cpu_clean_state(CPUState *cpu)
-{
- cpu->kvm_vcpu_dirty = false;
-}
-
int kvm_cpu_exec(CPUState *cpu)
{
struct kvm_run *run = cpu->kvm_run;
return;
}
+ if (listener->begin) {
+ listener->begin(listener);
+ }
if (global_dirty_log) {
if (listener->log_global_start) {
listener->log_global_start(listener);
.offset_within_address_space = int128_get64(fr->addr.start),
.readonly = fr->readonly,
};
+ if (fr->dirty_log_mask && listener->log_start) {
+ listener->log_start(listener, §ion, 0, fr->dirty_log_mask);
+ }
if (listener->region_add) {
listener->region_add(listener, §ion);
}
}
+ if (listener->commit) {
+ listener->commit(listener);
+ }
flatview_unref(view);
}
a memory backend that has hugepage support:
@example
-qemu-system-i386 -object memory-backend-file,size=1G,mem-path=/mnt/hugepages,id=mb1
+qemu-system-i386 -object memory-backend-file,size=1G,mem-path=/mnt/hugepages/my-shmem-file,id=mb1
-device ivshmem,memdev=mb1
@end example
"x86 only: show protected mode far calls/returns/exceptions" },
{ CPU_LOG_RESET, "cpu_reset",
"show CPU state before CPU resets" },
- { CPU_LOG_IOPORT, "ioport",
- "show all i/o ports accesses" },
{ LOG_UNIMP, "unimp",
"log unimplemented functionality" },
{ LOG_GUEST_ERROR, "guest_errors",
#include "qapi/qmp/qerror.h"
#include "qemu/queue.h"
#include "qemu/host-utils.h"
+#include "qemu/sockets.h"
#ifndef CONFIG_HAS_ENVIRON
#ifdef __APPLE__
return NULL;
}
-static int guest_file_toggle_flags(int fd, int flags, bool set, Error **err)
-{
- int ret, old_flags;
-
- old_flags = fcntl(fd, F_GETFL);
- if (old_flags == -1) {
- error_setg_errno(err, errno, QERR_QGA_COMMAND_FAILED,
- "failed to fetch filehandle flags");
- return -1;
- }
-
- ret = fcntl(fd, F_SETFL, set ? (old_flags | flags) : (old_flags & ~flags));
- if (ret == -1) {
- error_setg_errno(err, errno, QERR_QGA_COMMAND_FAILED,
- "failed to set filehandle flags");
- return -1;
- }
-
- return ret;
-}
-
int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode,
Error **errp)
{
/* set fd non-blocking to avoid common use cases (like reading from a
* named pipe) from hanging the agent
*/
- if (guest_file_toggle_flags(fileno(fh), O_NONBLOCK, true, errp) < 0) {
- fclose(fh);
- return -1;
- }
+ qemu_set_nonblock(fileno(fh));
handle = guest_file_handle_add(fh, errp);
if (handle < 0) {
return NULL;
}
+static void handle_set_nonblocking(HANDLE fh)
+{
+ DWORD file_type, pipe_state;
+ file_type = GetFileType(fh);
+ if (file_type != FILE_TYPE_PIPE) {
+ return;
+ }
+ /* If file_type == FILE_TYPE_PIPE, according to MSDN
+ * the specified file is socket or named pipe */
+ if (!GetNamedPipeHandleState(fh, &pipe_state, NULL,
+ NULL, NULL, NULL, 0)) {
+ return;
+ }
+ /* The fd is named pipe fd */
+ if (pipe_state & PIPE_NOWAIT) {
+ return;
+ }
+
+ pipe_state |= PIPE_NOWAIT;
+ SetNamedPipeHandleState(fh, &pipe_state, NULL, NULL);
+}
+
int64_t qmp_guest_file_open(const char *path, bool has_mode,
const char *mode, Error **errp)
{
return -1;
}
+ /* set fd non-blocking to avoid common use cases (like reading from a
+ * named pipe) from hanging the agent
+ */
+ handle_set_nonblocking(fh);
+
fd = guest_file_handle_add(fh, errp);
if (fd < 0) {
- CloseHandle(&fh);
+ CloseHandle(fh);
error_setg(errp, "failed to add handle to qmp handle table");
return -1;
}
@columns = ();
for $column (split (/\s*\@tab\s*/, $1)) {
# @strong{...} is used a @headitem work-alike
- $column =~ s/^\@strong{(.*)}$/$1/;
+ $column =~ s/^\@strong\{(.*)\}$/$1/;
push @columns, $column;
}
$_ = "\n=item ".join (" : ", @columns)."\n";
static const char *cpuid_7_0_ebx_feature_name[] = {
"fsgsbase", "tsc_adjust", NULL, "bmi1", "hle", "avx2", NULL, "smep",
"bmi2", "erms", "invpcid", "rtm", NULL, NULL, "mpx", NULL,
- "avx512f", NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
- NULL, NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL,
+ "avx512f", NULL, "rdseed", "adx", "smap", NULL, "pcommit", "clflushopt",
+ "clwb", NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL,
};
static const char *cpuid_apm_edx_feature_name[] = {
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
CPUID_PSE36,
.features[FEAT_1_ECX] =
- CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
+ CPUID_EXT_SSE3 | CPUID_EXT_CX16,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
.features[FEAT_8000_0001_ECX] =
- CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
- CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
+ CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
.xlevel = 0x8000000A,
},
{
.features[FEAT_1_EDX] =
PPRO_FEATURES,
.features[FEAT_1_ECX] =
- CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
+ CPUID_EXT_SSE3,
.xlevel = 0x80000004,
},
{
pstrcpy(def->model_id, sizeof(def->model_id),
"QEMU Virtual CPU version ");
pstrcat(def->model_id, sizeof(def->model_id),
- qemu_get_version());
+ qemu_hw_version());
break;
}
}
#define CPUID_7_0_EBX_RDSEED (1U << 18)
#define CPUID_7_0_EBX_ADX (1U << 19)
#define CPUID_7_0_EBX_SMAP (1U << 20)
+#define CPUID_7_0_EBX_PCOMMIT (1U << 22) /* Persistent Commit */
+#define CPUID_7_0_EBX_CLFLUSHOPT (1U << 23) /* Flush a Cache Line Optimized */
+#define CPUID_7_0_EBX_CLWB (1U << 24) /* Cache Line Write Back */
#define CPUID_7_0_EBX_AVX512PF (1U << 26) /* AVX-512 Prefetch */
#define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */
#define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */
return !kvm_irqchip_in_kernel() || kvm_has_gsi_routing();
}
+static int kvm_get_tsc(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+ struct {
+ struct kvm_msrs info;
+ struct kvm_msr_entry entries[1];
+ } msr_data;
+ int ret;
+
+ if (env->tsc_valid) {
+ return 0;
+ }
+
+ msr_data.info.nmsrs = 1;
+ msr_data.entries[0].index = MSR_IA32_TSC;
+ env->tsc_valid = !runstate_is_running();
+
+ ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data);
+ if (ret < 0) {
+ return ret;
+ }
+
+ env->tsc = msr_data.entries[0].data;
+ return 0;
+}
+
+static inline void do_kvm_synchronize_tsc(void *arg)
+{
+ CPUState *cpu = arg;
+
+ kvm_get_tsc(cpu);
+}
+
+void kvm_synchronize_all_tsc(void)
+{
+ CPUState *cpu;
+
+ if (kvm_enabled()) {
+ CPU_FOREACH(cpu) {
+ run_on_cpu(cpu, do_kvm_synchronize_tsc, cpu);
+ }
+ }
+}
+
static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
{
struct kvm_cpuid2 *cpuid;
bool kvm_allows_irq0_override(void);
bool kvm_has_smm(void);
+void kvm_synchronize_all_tsc(void);
void kvm_arch_reset_vcpu(X86CPU *cs);
void kvm_arch_do_init_vcpu(X86CPU *cs);
}
break;
case 3:
- for (j = valids - validd; j >= 0; j--) {
+ for (j = valids; j >= 0; j--) {
res <<= 1;
v = 1;
- for (i = MIN(upper - j, validd); i >= 0; i--) {
+ for (i = MIN(valids - j, validd); i >= 0; i--) {
v &= (pcmp_val(s, ctrl, i + j) == pcmp_val(d, ctrl, i));
}
res |= v;
paio_submit(void *acb, void *opaque, int64_t sector_num, int nb_sectors, int type) "acb %p opaque %p sector_num %"PRId64" nb_sectors %d type %d"
# ioport.c
-cpu_in(unsigned int addr, unsigned int val) "addr %#x value %u"
-cpu_out(unsigned int addr, unsigned int val) "addr %#x value %u"
+cpu_in(unsigned int addr, char size, unsigned int val) "addr %#x(%c) value %u"
+cpu_out(unsigned int addr, char size, unsigned int val) "addr %#x(%c) value %u"
# balloon.c
# Since requests are raised via monitor, not many tracepoints are needed.
static bool fips_enabled = false;
-static const char *qemu_version = QEMU_VERSION;
+static const char *hw_version = QEMU_VERSION;
int socket_set_cork(int fd, int v)
{
return ret;
}
-void qemu_set_version(const char *version)
+void qemu_set_hw_version(const char *version)
{
- qemu_version = version;
+ hw_version = version;
}
-const char *qemu_get_version(void)
+const char *qemu_hw_version(void)
{
- return qemu_version;
+ return hw_version;
}
void fips_set_state(bool requested)
cpu_exec_init_all();
if (machine_class->hw_version) {
- qemu_set_version(machine_class->hw_version);
+ qemu_set_hw_version(machine_class->hw_version);
}
/* Init CPU def lists, based on config