aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-12-17 18:07:09 +0000
committerPeter Maydell <peter.maydell@linaro.org>2015-12-17 18:07:09 +0000
commit6a6533213d78dea4407fe6933ad489796b582599 (patch)
tree1e37b82b21a52c000d5d6de0494c168bd69d4307
parente5fbe28e5424d26fc2c25d0a7ecb927d3c80d5e8 (diff)
parent29cd81ffe3679bec9a062505e5b0d9a12f3558a8 (diff)
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* KVM: synic support, split irqchip support * memory: cleanups, optimizations, ioeventfd emulation * SCSI: small fixes, vmw_pvscsi compatibility improvements * qemu_log cleanups * Coverity model improvements # gpg: Signature made Thu 17 Dec 2015 16:35:21 GMT using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" * remotes/bonzini/tags/for-upstream: (45 commits) coverity: Model g_memdup() coverity: Model g_poll() scsi: always call notifier on async cancellation scsi: use scsi_req_cancel_async when purging requests target-i386: kvm: clear unusable segments' flags in migration rcu: optimize rcu_read_lock memory: try to inline constant-length reads memory: inline a few small accessors memory: extract first iteration of address_space_read and address_space_write memory: split address_space_read and address_space_write memory: avoid unnecessary object_ref/unref memory: reorder MemoryRegion fields exec: make qemu_ram_ptr_length more similar to qemu_get_ram_ptr exec: always call qemu_get_ram_ptr within rcu_read_lock linux-user: convert DEBUG_SIGNAL logging to tracepoints linux-user: avoid "naked" qemu_log user: introduce "-d page" xtensa: avoid "naked" qemu_log tricore: avoid "naked" qemu_log ppc: cleanup logging ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--bsd-user/main.c4
-rw-r--r--bsd-user/signal.c2
-rw-r--r--default-configs/i386-softmmu.mak1
-rw-r--r--default-configs/x86_64-softmmu.mak1
-rw-r--r--exec.c365
-rw-r--r--hw/alpha/pci.c3
-rw-r--r--hw/char/etraxfs_ser.c2
-rw-r--r--hw/core/machine.c49
-rw-r--r--hw/display/virtio-gpu.c4
-rw-r--r--hw/i386/pc.c5
-rw-r--r--hw/i386/pc_piix.c5
-rw-r--r--hw/intc/ioapic.c68
-rw-r--r--hw/misc/Makefile.objs1
-rw-r--r--hw/misc/hyperv_testdev.c167
-rw-r--r--hw/scsi/scsi-bus.c9
-rw-r--r--hw/scsi/vmw_pvscsi.c96
-rw-r--r--include/exec/memory.h136
-rw-r--r--include/exec/ram_addr.h2
-rw-r--r--include/hw/boards.h2
-rw-r--r--include/hw/compat.h8
-rw-r--r--include/hw/i386/pc.h13
-rw-r--r--include/qemu/log.h8
-rw-r--r--include/qemu/rcu.h6
-rw-r--r--include/standard-headers/asm-x86/hyperv.h104
-rw-r--r--include/standard-headers/linux/input-event-codes.h805
-rw-r--r--include/standard-headers/linux/input.h850
-rw-r--r--include/standard-headers/linux/pci_regs.h43
-rw-r--r--include/standard-headers/linux/virtio_gpu.h2
-rw-r--r--include/sysemu/kvm.h18
-rw-r--r--kvm-all.c55
-rw-r--r--linux-headers/asm-arm64/kvm.h2
-rw-r--r--linux-headers/asm-powerpc/unistd.h13
-rw-r--r--linux-headers/asm-s390/kvm.h2
-rw-r--r--linux-headers/asm-s390/unistd.h19
-rw-r--r--linux-headers/asm-x86/unistd_32.h1
-rw-r--r--linux-headers/asm-x86/unistd_64.h1
-rw-r--r--linux-headers/asm-x86/unistd_x32.h1
-rw-r--r--linux-headers/linux/kvm.h25
-rw-r--r--linux-headers/linux/psci.h18
-rw-r--r--linux-user/elfload.c8
-rw-r--r--linux-user/main.c75
-rw-r--r--linux-user/signal.c118
-rw-r--r--memory.c111
-rw-r--r--qapi-schema.json5
-rw-r--r--qapi/common.json16
-rw-r--r--qemu-char.c14
-rw-r--r--qemu-log.c2
-rw-r--r--qemu-options.hx3
-rw-r--r--scripts/coverity-model.c26
-rwxr-xr-xscripts/update-linux-headers.sh3
-rw-r--r--stubs/kvm.c2
-rw-r--r--target-arm/kvm.c8
-rw-r--r--target-cris/helper.h1
-rw-r--r--target-cris/op_helper.c5
-rw-r--r--target-cris/translate.c8
-rw-r--r--target-cris/translate_v10.c2
-rw-r--r--target-i386/Makefile.objs2
-rw-r--r--target-i386/cpu-qom.h2
-rw-r--r--target-i386/cpu.c4
-rw-r--r--target-i386/cpu.h7
-rw-r--r--target-i386/hyperv.c127
-rw-r--r--target-i386/hyperv.h42
-rw-r--r--target-i386/kvm.c184
-rw-r--r--target-i386/kvm_i386.h2
-rw-r--r--target-i386/machine.c66
-rw-r--r--target-microblaze/helper.c2
-rw-r--r--target-microblaze/mmu.c20
-rw-r--r--target-microblaze/op_helper.c8
-rw-r--r--target-microblaze/translate.c2
-rw-r--r--target-ppc/excp_helper.c8
-rw-r--r--target-ppc/mmu-hash32.c12
-rw-r--r--target-ppc/mmu-hash64.c9
-rw-r--r--target-ppc/mmu_helper.c15
-rw-r--r--target-ppc/timebase_helper.c10
-rw-r--r--target-ppc/translate.c62
-rw-r--r--target-s390x/cc_helper.c2
-rw-r--r--target-s390x/helper.c2
-rw-r--r--target-s390x/misc_helper.c2
-rw-r--r--target-s390x/mmu_helper.c2
-rw-r--r--target-tricore/helper.c4
-rw-r--r--target-xtensa/gdbstub.c8
-rw-r--r--target-xtensa/helper.c4
-rw-r--r--target-xtensa/op_helper.c20
-rw-r--r--target-xtensa/translate.c28
-rw-r--r--target-xtensa/xtensa-semi.c2
-rw-r--r--trace-events14
86 files changed, 2649 insertions, 1346 deletions
diff --git a/bsd-user/main.c b/bsd-user/main.c
index adf2de0d90..1ecaeb50e5 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -938,7 +938,7 @@ int main(int argc, char **argv)
unsigned long tmp;
if (fscanf(fp, "%lu", &tmp) == 1) {
mmap_min_addr = tmp;
- qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
+ qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n", mmap_min_addr);
}
fclose(fp);
}
@@ -955,7 +955,7 @@ int main(int argc, char **argv)
free(target_environ);
- if (qemu_log_enabled()) {
+ if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
qemu_log("guest_base 0x%lx\n", guest_base);
log_page_dump();
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index e4ee2d0e80..4887ecc617 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -26,8 +26,6 @@
#include "qemu.h"
#include "target_signal.h"
-//#define DEBUG_SIGNAL
-
void signal_init(void)
{
}
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 43c96d1c91..57ccff33e3 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -50,3 +50,4 @@ CONFIG_XIO3130=y
CONFIG_IOH3420=y
CONFIG_I82801B11=y
CONFIG_SMBIOS=y
+CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index dfb80954d4..30f5e751e6 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -50,3 +50,4 @@ CONFIG_XIO3130=y
CONFIG_IOH3420=y
CONFIG_I82801B11=y
CONFIG_SMBIOS=y
+CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
diff --git a/exec.c b/exec.c
index 0bf0a6e7eb..8718a75b64 100644
--- a/exec.c
+++ b/exec.c
@@ -88,9 +88,6 @@ static MemoryRegion io_mem_unassigned;
*/
#define RAM_RESIZEABLE (1 << 2)
-/* RAM is backed by an mmapped file.
- */
-#define RAM_FILE (1 << 3)
#endif
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
@@ -393,18 +390,6 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
return section;
}
-static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
-{
- if (memory_region_is_ram(mr)) {
- return !(is_write && mr->readonly);
- }
- if (memory_region_is_romd(mr)) {
- return !is_write;
- }
-
- return false;
-}
-
/* Called from RCU critical section */
MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
hwaddr *xlat, hwaddr *plen,
@@ -873,7 +858,7 @@ void cpu_abort(CPUState *cpu, const char *fmt, ...)
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP);
- if (qemu_log_enabled()) {
+ if (qemu_log_separate()) {
qemu_log("qemu: fatal: ");
qemu_log_vprintf(fmt, ap2);
qemu_log("\n");
@@ -1601,7 +1586,6 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
new_block->used_length = size;
new_block->max_length = size;
new_block->flags = share ? RAM_SHARED : 0;
- new_block->flags |= RAM_FILE;
new_block->host = file_ram_alloc(new_block, size,
mem_path, errp);
if (!new_block->host) {
@@ -1676,25 +1660,6 @@ ram_addr_t qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t maxsz,
return qemu_ram_alloc_internal(size, maxsz, resized, NULL, true, mr, errp);
}
-void qemu_ram_free_from_ptr(ram_addr_t addr)
-{
- RAMBlock *block;
-
- qemu_mutex_lock_ramlist();
- QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
- if (addr == block->offset) {
- QLIST_REMOVE_RCU(block, next);
- ram_list.mru_block = NULL;
- /* Write list before version */
- smp_wmb();
- ram_list.version++;
- g_free_rcu(block, rcu);
- break;
- }
- }
- qemu_mutex_unlock_ramlist();
-}
-
static void reclaim_ramblock(RAMBlock *block)
{
if (block->flags & RAM_PREALLOC) {
@@ -1703,11 +1668,7 @@ static void reclaim_ramblock(RAMBlock *block)
xen_invalidate_map_cache_entry(block->host);
#ifndef _WIN32
} else if (block->fd >= 0) {
- if (block->flags & RAM_FILE) {
- qemu_ram_munmap(block->host, block->max_length);
- } else {
- munmap(block->host, block->max_length);
- }
+ qemu_ram_munmap(block->host, block->max_length);
close(block->fd);
#endif
} else {
@@ -1813,19 +1774,11 @@ void *qemu_get_ram_block_host_ptr(ram_addr_t addr)
* or address_space_rw instead. For local memory (e.g. video ram) that the
* device owns, use memory_region_get_ram_ptr.
*
- * By the time this function returns, the returned pointer is not protected
- * by RCU anymore. If the caller is not within an RCU critical section and
- * does not hold the iothread lock, it must have other means of protecting the
- * pointer, such as a reference to the region that includes the incoming
- * ram_addr_t.
+ * Called within RCU critical section.
*/
void *qemu_get_ram_ptr(ram_addr_t addr)
{
- RAMBlock *block;
- void *ptr;
-
- rcu_read_lock();
- block = qemu_get_ram_block(addr);
+ RAMBlock *block = qemu_get_ram_block(addr);
if (xen_enabled() && block->host == NULL) {
/* We need to check if the requested address is in the RAM
@@ -1833,52 +1786,44 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
* In that case just map until the end of the page.
*/
if (block->offset == 0) {
- ptr = xen_map_cache(addr, 0, 0);
- goto unlock;
+ return xen_map_cache(addr, 0, 0);
}
block->host = xen_map_cache(block->offset, block->max_length, 1);
}
- ptr = ramblock_ptr(block, addr - block->offset);
-
-unlock:
- rcu_read_unlock();
- return ptr;
+ return ramblock_ptr(block, addr - block->offset);
}
/* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr
* but takes a size argument.
*
- * By the time this function returns, the returned pointer is not protected
- * by RCU anymore. If the caller is not within an RCU critical section and
- * does not hold the iothread lock, it must have other means of protecting the
- * pointer, such as a reference to the region that includes the incoming
- * ram_addr_t.
+ * Called within RCU critical section.
*/
static void *qemu_ram_ptr_length(ram_addr_t addr, hwaddr *size)
{
- void *ptr;
+ RAMBlock *block;
+ ram_addr_t offset_inside_block;
if (*size == 0) {
return NULL;
}
- if (xen_enabled()) {
- return xen_map_cache(addr, *size, 1);
- } else {
- RAMBlock *block;
- rcu_read_lock();
- QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
- if (addr - block->offset < block->max_length) {
- if (addr - block->offset + *size > block->max_length)
- *size = block->max_length - addr + block->offset;
- ptr = ramblock_ptr(block, addr - block->offset);
- rcu_read_unlock();
- return ptr;
- }
+
+ block = qemu_get_ram_block(addr);
+ offset_inside_block = addr - block->offset;
+ *size = MIN(*size, block->max_length - offset_inside_block);
+
+ if (xen_enabled() && block->host == NULL) {
+ /* We need to check if the requested address is in the RAM
+ * because we don't want to map the entire memory in QEMU.
+ * In that case just map the requested area.
+ */
+ if (block->offset == 0) {
+ return xen_map_cache(addr, *size, 1);
}
- fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
- abort();
+ block->host = xen_map_cache(block->offset, block->max_length, 1);
}
+
+ return ramblock_ptr(block, offset_inside_block);
}
/*
@@ -1981,6 +1926,7 @@ MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
return block->mr;
}
+/* Called within RCU critical section. */
static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
uint64_t val, unsigned size)
{
@@ -2511,101 +2457,58 @@ static bool prepare_mmio_access(MemoryRegion *mr)
return release_lock;
}
-MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
- uint8_t *buf, int len, bool is_write)
+/* Called within RCU critical section. */
+static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
+ MemTxAttrs attrs,
+ const uint8_t *buf,
+ int len, hwaddr addr1,
+ hwaddr l, MemoryRegion *mr)
{
- hwaddr l;
uint8_t *ptr;
uint64_t val;
- hwaddr addr1;
- MemoryRegion *mr;
MemTxResult result = MEMTX_OK;
bool release_lock = false;
- rcu_read_lock();
- while (len > 0) {
- l = len;
- mr = address_space_translate(as, addr, &addr1, &l, is_write);
-
- if (is_write) {
- if (!memory_access_is_direct(mr, is_write)) {
- release_lock |= prepare_mmio_access(mr);
- l = memory_access_size(mr, l, addr1);
- /* XXX: could force current_cpu to NULL to avoid
- potential bugs */
- switch (l) {
- case 8:
- /* 64 bit write access */
- val = ldq_p(buf);
- result |= memory_region_dispatch_write(mr, addr1, val, 8,
- attrs);
- break;
- case 4:
- /* 32 bit write access */
- val = ldl_p(buf);
- result |= memory_region_dispatch_write(mr, addr1, val, 4,
- attrs);
- break;
- case 2:
- /* 16 bit write access */
- val = lduw_p(buf);
- result |= memory_region_dispatch_write(mr, addr1, val, 2,
- attrs);
- break;
- case 1:
- /* 8 bit write access */
- val = ldub_p(buf);
- result |= memory_region_dispatch_write(mr, addr1, val, 1,
- attrs);
- break;
- default:
- abort();
- }
- } else {
- addr1 += memory_region_get_ram_addr(mr);
- /* RAM case */
- ptr = qemu_get_ram_ptr(addr1);
- memcpy(ptr, buf, l);
- invalidate_and_set_dirty(mr, addr1, l);
+ for (;;) {
+ if (!memory_access_is_direct(mr, true)) {
+ release_lock |= prepare_mmio_access(mr);
+ l = memory_access_size(mr, l, addr1);
+ /* XXX: could force current_cpu to NULL to avoid
+ potential bugs */
+ switch (l) {
+ case 8:
+ /* 64 bit write access */
+ val = ldq_p(buf);
+ result |= memory_region_dispatch_write(mr, addr1, val, 8,
+ attrs);
+ break;
+ case 4:
+ /* 32 bit write access */
+ val = ldl_p(buf);
+ result |= memory_region_dispatch_write(mr, addr1, val, 4,
+ attrs);
+ break;
+ case 2:
+ /* 16 bit write access */
+ val = lduw_p(buf);
+ result |= memory_region_dispatch_write(mr, addr1, val, 2,
+ attrs);
+ break;
+ case 1:
+ /* 8 bit write access */
+ val = ldub_p(buf);
+ result |= memory_region_dispatch_write(mr, addr1, val, 1,
+ attrs);
+ break;
+ default:
+ abort();
}
} else {
- if (!memory_access_is_direct(mr, is_write)) {
- /* I/O case */
- release_lock |= prepare_mmio_access(mr);
- l = memory_access_size(mr, l, addr1);
- switch (l) {
- case 8:
- /* 64 bit read access */
- result |= memory_region_dispatch_read(mr, addr1, &val, 8,
- attrs);
- stq_p(buf, val);
- break;
- case 4:
- /* 32 bit read access */
- result |= memory_region_dispatch_read(mr, addr1, &val, 4,
- attrs);
- stl_p(buf, val);
- break;
- case 2:
- /* 16 bit read access */
- result |= memory_region_dispatch_read(mr, addr1, &val, 2,
- attrs);
- stw_p(buf, val);
- break;
- case 1:
- /* 8 bit read access */
- result |= memory_region_dispatch_read(mr, addr1, &val, 1,
- attrs);
- stb_p(buf, val);
- break;
- default:
- abort();
- }
- } else {
- /* RAM case */
- ptr = qemu_get_ram_ptr(mr->ram_addr + addr1);
- memcpy(buf, ptr, l);
- }
+ addr1 += memory_region_get_ram_addr(mr);
+ /* RAM case */
+ ptr = qemu_get_ram_ptr(addr1);
+ memcpy(ptr, buf, l);
+ invalidate_and_set_dirty(mr, addr1, l);
}
if (release_lock) {
@@ -2616,8 +2519,14 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
len -= l;
buf += l;
addr += l;
+
+ if (!len) {
+ break;
+ }
+
+ l = len;
+ mr = address_space_translate(as, addr, &addr1, &l, true);
}
- rcu_read_unlock();
return result;
}
@@ -2625,15 +2534,122 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
const uint8_t *buf, int len)
{
- return address_space_rw(as, addr, attrs, (uint8_t *)buf, len, true);
+ hwaddr l;
+ hwaddr addr1;
+ MemoryRegion *mr;
+ MemTxResult result = MEMTX_OK;
+
+ if (len > 0) {
+ rcu_read_lock();
+ l = len;
+ mr = address_space_translate(as, addr, &addr1, &l, true);
+ result = address_space_write_continue(as, addr, attrs, buf, len,
+ addr1, l, mr);
+ rcu_read_unlock();
+ }
+
+ return result;
}
-MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
- uint8_t *buf, int len)
+/* Called within RCU critical section. */
+MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
+ MemTxAttrs attrs, uint8_t *buf,
+ int len, hwaddr addr1, hwaddr l,
+ MemoryRegion *mr)
{
- return address_space_rw(as, addr, attrs, buf, len, false);
+ uint8_t *ptr;
+ uint64_t val;
+ MemTxResult result = MEMTX_OK;
+ bool release_lock = false;
+
+ for (;;) {
+ if (!memory_access_is_direct(mr, false)) {
+ /* I/O case */
+ release_lock |= prepare_mmio_access(mr);
+ l = memory_access_size(mr, l, addr1);
+ switch (l) {
+ case 8:
+ /* 64 bit read access */
+ result |= memory_region_dispatch_read(mr, addr1, &val, 8,
+ attrs);
+ stq_p(buf, val);
+ break;
+ case 4:
+ /* 32 bit read access */
+ result |= memory_region_dispatch_read(mr, addr1, &val, 4,
+ attrs);
+ stl_p(buf, val);
+ break;
+ case 2:
+ /* 16 bit read access */
+ result |= memory_region_dispatch_read(mr, addr1, &val, 2,
+ attrs);
+ stw_p(buf, val);
+ break;
+ case 1:
+ /* 8 bit read access */
+ result |= memory_region_dispatch_read(mr, addr1, &val, 1,
+ attrs);
+ stb_p(buf, val);
+ break;
+ default:
+ abort();
+ }
+ } else {
+ /* RAM case */
+ ptr = qemu_get_ram_ptr(mr->ram_addr + addr1);
+ memcpy(buf, ptr, l);
+ }
+
+ if (release_lock) {
+ qemu_mutex_unlock_iothread();
+ release_lock = false;
+ }
+
+ len -= l;
+ buf += l;
+ addr += l;
+
+ if (!len) {
+ break;
+ }
+
+ l = len;
+ mr = address_space_translate(as, addr, &addr1, &l, false);
+ }
+
+ return result;
}
+MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
+ MemTxAttrs attrs, uint8_t *buf, int len)
+{
+ hwaddr l;
+ hwaddr addr1;
+ MemoryRegion *mr;
+ MemTxResult result = MEMTX_OK;
+
+ if (len > 0) {
+ rcu_read_lock();
+ l = len;
+ mr = address_space_translate(as, addr, &addr1, &l, false);
+ result = address_space_read_continue(as, addr, attrs, buf, len,
+ addr1, l, mr);
+ rcu_read_unlock();
+ }
+
+ return result;
+}
+
+MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
+ uint8_t *buf, int len, bool is_write)
+{
+ if (is_write) {
+ return address_space_write(as, addr, attrs, (uint8_t *)buf, len);
+ } else {
+ return address_space_read(as, addr, attrs, (uint8_t *)buf, len);
+ }
+}
void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
int len, int is_write)
@@ -2825,6 +2841,7 @@ void *address_space_map(AddressSpace *as,
hwaddr l, xlat, base;
MemoryRegion *mr, *this_mr;
ram_addr_t raddr;
+ void *ptr;
if (len == 0) {
return NULL;
@@ -2876,9 +2893,11 @@ void *address_space_map(AddressSpace *as,
}
memory_region_ref(mr);
- rcu_read_unlock();
*plen = done;
- return qemu_ram_ptr_length(raddr + base, plen);
+ ptr = qemu_ram_ptr_length(raddr + base, plen);
+ rcu_read_unlock();
+
+ return ptr;
}
/* Unmaps a memory region previously mapped by address_space_map().
diff --git a/hw/alpha/pci.c b/hw/alpha/pci.c
index d839dd556a..5226e43b96 100644
--- a/hw/alpha/pci.c
+++ b/hw/alpha/pci.c
@@ -10,6 +10,7 @@
#include "alpha_sys.h"
#include "qemu/log.h"
#include "sysemu/sysemu.h"
+#include "trace.h"
/* Fallback for unassigned PCI I/O operations. Avoids MCHK. */
@@ -73,7 +74,7 @@ static uint64_t iack_read(void *opaque, hwaddr addr, unsigned size)
static void special_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
- qemu_log("pci: special write cycle");
+ trace_alpha_pci_iack_write();
}
const MemoryRegionOps alpha_pci_iack_ops = {
diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c
index 562021e28b..d4d875e7a6 100644
--- a/hw/char/etraxfs_ser.c
+++ b/hw/char/etraxfs_ser.c
@@ -165,7 +165,7 @@ static void serial_receive(void *opaque, const uint8_t *buf, int size)
/* Got a byte. */
if (s->rx_fifo_len >= 16) {
- qemu_log("WARNING: UART dropped char.\n");
+ D(qemu_log("WARNING: UART dropped char.\n"));
return;
}
diff --git a/hw/core/machine.c b/hw/core/machine.c
index acca00db22..82be54e751 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -11,6 +11,7 @@
*/
#include "hw/boards.h"
+#include "qapi-visit.h"
#include "qapi/visitor.h"
#include "hw/sysbus.h"
#include "sysemu/sysemu.h"
@@ -31,12 +32,39 @@ static void machine_set_accel(Object *obj, const char *value, Error **errp)
ms->accel = g_strdup(value);
}
-static void machine_set_kernel_irqchip(Object *obj, bool value, Error **errp)
+static void machine_set_kernel_irqchip(Object *obj, Visitor *v,
+ void *opaque, const char *name,
+ Error **errp)
{
+ Error *err = NULL;
MachineState *ms = MACHINE(obj);
+ OnOffSplit mode;
- ms->kernel_irqchip_allowed = value;
- ms->kernel_irqchip_required = value;
+ visit_type_OnOffSplit(v, &mode, name, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ } else {
+ switch (mode) {
+ case ON_OFF_SPLIT_ON:
+ ms->kernel_irqchip_allowed = true;
+ ms->kernel_irqchip_required = true;
+ ms->kernel_irqchip_split = false;
+ break;
+ case ON_OFF_SPLIT_OFF:
+ ms->kernel_irqchip_allowed = false;
+ ms->kernel_irqchip_required = false;
+ ms->kernel_irqchip_split = false;
+ break;
+ case ON_OFF_SPLIT_SPLIT:
+ ms->kernel_irqchip_allowed = true;
+ ms->kernel_irqchip_required = true;
+ ms->kernel_irqchip_split = true;
+ break;
+ default:
+ abort();
+ }
+ }
}
static void machine_get_kvm_shadow_mem(Object *obj, Visitor *v,
@@ -341,12 +369,12 @@ static void machine_initfn(Object *obj)
object_property_set_description(obj, "accel",
"Accelerator list",
NULL);
- object_property_add_bool(obj, "kernel-irqchip",
- NULL,
- machine_set_kernel_irqchip,
- NULL);
+ object_property_add(obj, "kernel-irqchip", "OnOffSplit",
+ NULL,
+ machine_set_kernel_irqchip,
+ NULL, NULL, NULL);
object_property_set_description(obj, "kernel-irqchip",
- "Use KVM in-kernel irqchip",
+ "Configure KVM in-kernel irqchip",
NULL);
object_property_add(obj, "kvm-shadow-mem", "int",
machine_get_kvm_shadow_mem,
@@ -472,6 +500,11 @@ bool machine_kernel_irqchip_required(MachineState *machine)
return machine->kernel_irqchip_required;
}
+bool machine_kernel_irqchip_split(MachineState *machine)
+{
+ return machine->kernel_irqchip_split;
+}
+
int machine_kvm_shadow_mem(MachineState *machine)
{
return machine->kvm_shadow_mem;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index a836ce3859..7e79a9c86c 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -146,14 +146,14 @@ static uint64_t virtio_gpu_get_features(VirtIODevice *vdev, uint64_t features,
VirtIOGPU *g = VIRTIO_GPU(vdev);
if (virtio_gpu_virgl_enabled(g->conf)) {
- features |= (1 << VIRTIO_GPU_FEATURE_VIRGL);
+ features |= (1 << VIRTIO_GPU_F_VIRGL);
}
return features;
}
static void virtio_gpu_set_features(VirtIODevice *vdev, uint64_t features)
{
- static const uint32_t virgl = (1 << VIRTIO_GPU_FEATURE_VIRGL);
+ static const uint32_t virgl = (1 << VIRTIO_GPU_F_VIRGL);
VirtIOGPU *g = VIRTIO_GPU(vdev);
g->use_virgl_renderer = ((features & virgl) == virgl);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 5e20e07b6f..426424a721 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -65,6 +65,7 @@
#include "hw/mem/pc-dimm.h"
#include "qapi/visitor.h"
#include "qapi-visit.h"
+#include "qom/cpu.h"
/* debug PC/ISA interrupts */
//#define DEBUG_IRQ
@@ -1517,7 +1518,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
qemu_register_boot_set(pc_boot_set, *rtc_state);
if (!xen_enabled()) {
- if (kvm_irqchip_in_kernel()) {
+ if (kvm_pit_in_kernel()) {
pit = kvm_pit_init(isa_bus, 0x40);
} else {
pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq);
@@ -1592,7 +1593,7 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
SysBusDevice *d;
unsigned int i;
- if (kvm_irqchip_in_kernel()) {
+ if (kvm_ioapic_in_kernel()) {
dev = qdev_create(NULL, "kvm-ioapic");
} else {
dev = qdev_create(NULL, "ioapic");
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index abb377aab9..319497e966 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -53,6 +53,7 @@
#include "hw/xen/xen_pt.h"
#endif
#include "migration/migration.h"
+#include "kvm_i386.h"
#define MAX_IDE_BUS 2
@@ -181,7 +182,7 @@ static void pc_init1(MachineState *machine,
}
gsi_state = g_malloc0(sizeof(*gsi_state));
- if (kvm_irqchip_in_kernel()) {
+ if (kvm_ioapic_in_kernel()) {
kvm_pc_setup_irq_routing(pci_enabled);
gsi = qemu_allocate_irqs(kvm_pc_gsi_handler, gsi_state,
GSI_NUM_PINS);
@@ -205,7 +206,7 @@ static void pc_init1(MachineState *machine,
}
isa_bus_irqs(isa_bus, gsi);
- if (kvm_irqchip_in_kernel()) {
+ if (kvm_pic_in_kernel()) {
i8259 = kvm_i8259_init(isa_bus);
} else if (xen_enabled()) {
i8259 = xen_interrupt_controller_init();
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index de2dd4ba8e..e4bfaeade2 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -25,6 +25,8 @@
#include "hw/i386/pc.h"
#include "hw/i386/ioapic.h"
#include "hw/i386/ioapic_internal.h"
+#include "include/hw/pci/msi.h"
+#include "sysemu/kvm.h"
//#define DEBUG_IOAPIC
@@ -35,6 +37,10 @@
#define DPRINTF(fmt, ...)
#endif
+#define APIC_DELIVERY_MODE_SHIFT 8
+#define APIC_POLARITY_SHIFT 14
+#define APIC_TRIG_MODE_SHIFT 15
+
static IOAPICCommonState *ioapics[MAX_IOAPICS];
/* global variable from ioapic_common.c */
@@ -54,6 +60,8 @@ static void ioapic_service(IOAPICCommonState *s)
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
mask = 1 << i;
if (s->irr & mask) {
+ int coalesce = 0;
+
entry = s->ioredtbl[i];
if (!(entry & IOAPIC_LVT_MASKED)) {
trig_mode = ((entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1);
@@ -64,6 +72,7 @@ static void ioapic_service(IOAPICCommonState *s)
if (trig_mode == IOAPIC_TRIGGER_EDGE) {
s->irr &= ~mask;
} else {
+ coalesce = s->ioredtbl[i] & IOAPIC_LVT_REMOTE_IRR;
s->ioredtbl[i] |= IOAPIC_LVT_REMOTE_IRR;
}
if (delivery_mode == IOAPIC_DM_EXTINT) {
@@ -71,8 +80,23 @@ static void ioapic_service(IOAPICCommonState *s)
} else {
vector = entry & IOAPIC_VECTOR_MASK;
}
- apic_deliver_irq(dest, dest_mode, delivery_mode,
- vector, trig_mode);
+#ifdef CONFIG_KVM
+ if (kvm_irqchip_is_split()) {
+ if (trig_mode == IOAPIC_TRIGGER_EDGE) {
+ kvm_set_irq(kvm_state, i, 1);
+ kvm_set_irq(kvm_state, i, 0);
+ } else {
+ if (!coalesce) {
+ kvm_set_irq(kvm_state, i, 1);
+ }
+ }
+ continue;
+ }
+#else
+ (void)coalesce;
+#endif
+ apic_deliver_irq(dest, dest_mode, delivery_mode, vector,
+ trig_mode);
}
}
}
@@ -116,6 +140,44 @@ static void ioapic_set_irq(void *opaque, int vector, int level)
}
}
+static void ioapic_update_kvm_routes(IOAPICCommonState *s)
+{
+#ifdef CONFIG_KVM
+ int i;
+
+ if (kvm_irqchip_is_split()) {
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ uint64_t entry = s->ioredtbl[i];
+ uint8_t trig_mode;
+ uint8_t delivery_mode;
+ uint8_t dest;
+ uint8_t dest_mode;
+ uint64_t pin_polarity;
+ MSIMessage msg;
+
+ trig_mode = ((entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1);
+ dest = entry >> IOAPIC_LVT_DEST_SHIFT;
+ dest_mode = (entry >> IOAPIC_LVT_DEST_MODE_SHIFT) & 1;
+ pin_polarity = (entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1;
+ delivery_mode =
+ (entry >> IOAPIC_LVT_DELIV_MODE_SHIFT) & IOAPIC_DM_MASK;
+
+ msg.address = APIC_DEFAULT_ADDRESS;
+ msg.address |= dest_mode << 2;
+ msg.address |= dest << 12;
+
+ msg.data = entry & IOAPIC_VECTOR_MASK;
+ msg.data |= delivery_mode << APIC_DELIVERY_MODE_SHIFT;
+ msg.data |= pin_polarity << APIC_POLARITY_SHIFT;
+ msg.data |= trig_mode << APIC_TRIG_MODE_SHIFT;
+
+ kvm_irqchip_update_msi_route(kvm_state, i, msg, NULL);
+ }
+ kvm_irqchip_commit_routes(kvm_state);
+ }
+#endif
+}
+
void ioapic_eoi_broadcast(int vector)
{
IOAPICCommonState *s;
@@ -229,6 +291,8 @@ ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
}
break;
}
+
+ ioapic_update_kvm_routes(s);
}
static const MemoryRegionOps ioapic_io_ops = {
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 8a235dfb57..d4765c2516 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -43,3 +43,4 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
obj-$(CONFIG_PVPANIC) += pvpanic.o
obj-$(CONFIG_EDU) += edu.o
+obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
diff --git a/hw/misc/hyperv_testdev.c b/hw/misc/hyperv_testdev.c
new file mode 100644
index 0000000000..d88844aaba
--- /dev/null
+++ b/hw/misc/hyperv_testdev.c
@@ -0,0 +1,167 @@
+/*
+ * QEMU KVM Hyper-V test device to support Hyper-V kvm-unit-tests
+ *
+ * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
+ *
+ * Authors:
+ * Andrey Smetanin <asmetanin@virtuozzo.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw/hw.h"
+#include "hw/qdev.h"
+#include "hw/isa/isa.h"
+#include "sysemu/kvm.h"
+#include "linux/kvm.h"
+#include "target-i386/hyperv.h"
+#include "kvm_i386.h"
+
+#define HV_TEST_DEV_MAX_SINT_ROUTES 64
+
+struct HypervTestDev {
+ ISADevice parent_obj;
+ MemoryRegion sint_control;
+ HvSintRoute *sint_route[HV_TEST_DEV_MAX_SINT_ROUTES];
+};
+typedef struct HypervTestDev HypervTestDev;
+
+#define TYPE_HYPERV_TEST_DEV "hyperv-testdev"
+#define HYPERV_TEST_DEV(obj) \
+ OBJECT_CHECK(HypervTestDev, (obj), TYPE_HYPERV_TEST_DEV)
+
+enum {
+ HV_TEST_DEV_SINT_ROUTE_CREATE = 1,
+ HV_TEST_DEV_SINT_ROUTE_DESTROY,
+ HV_TEST_DEV_SINT_ROUTE_SET_SINT
+};
+
+static int alloc_sint_route_index(HypervTestDev *dev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dev->sint_route); i++) {
+ if (dev->sint_route[i] == NULL) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static void free_sint_route_index(HypervTestDev *dev, int i)
+{
+ assert(i >= 0 && i < ARRAY_SIZE(dev->sint_route));
+ dev->sint_route[i] = NULL;
+}
+
+static int find_sint_route_index(HypervTestDev *dev, uint32_t vcpu_id,
+ uint32_t sint)
+{
+ HvSintRoute *sint_route;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dev->sint_route); i++) {
+ sint_route = dev->sint_route[i];
+ if (sint_route && sint_route->vcpu_id == vcpu_id &&
+ sint_route->sint == sint) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static void hv_synic_test_dev_control(HypervTestDev *dev, uint32_t ctl,
+ uint32_t vcpu_id, uint32_t sint)
+{
+ int i;
+ HvSintRoute *sint_route;
+
+ switch (ctl) {
+ case HV_TEST_DEV_SINT_ROUTE_CREATE:
+ i = alloc_sint_route_index(dev);
+ assert(i >= 0);
+ sint_route = kvm_hv_sint_route_create(vcpu_id, sint, NULL);
+ assert(sint_route);
+ dev->sint_route[i] = sint_route;
+ break;
+ case HV_TEST_DEV_SINT_ROUTE_DESTROY:
+ i = find_sint_route_index(dev, vcpu_id, sint);
+ assert(i >= 0);
+ sint_route = dev->sint_route[i];
+ kvm_hv_sint_route_destroy(sint_route);
+ free_sint_route_index(dev, i);
+ break;
+ case HV_TEST_DEV_SINT_ROUTE_SET_SINT:
+ i = find_sint_route_index(dev, vcpu_id, sint);
+ assert(i >= 0);
+ sint_route = dev->sint_route[i];
+ kvm_hv_sint_route_set_sint(sint_route);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hv_test_dev_control(void *opaque, hwaddr addr, uint64_t data,
+ uint32_t len)
+{
+ HypervTestDev *dev = HYPERV_TEST_DEV(opaque);
+ uint8_t ctl;
+
+ ctl = (data >> 16ULL) & 0xFF;
+ switch (ctl) {
+ case HV_TEST_DEV_SINT_ROUTE_CREATE:
+ case HV_TEST_DEV_SINT_ROUTE_DESTROY:
+ case HV_TEST_DEV_SINT_ROUTE_SET_SINT: {
+ uint8_t sint = data & 0xFF;
+ uint8_t vcpu_id = (data >> 8ULL) & 0xFF;
+ hv_synic_test_dev_control(dev, ctl, vcpu_id, sint);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static const MemoryRegionOps synic_test_sint_ops = {
+ .write = hv_test_dev_control,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void hv_test_dev_realizefn(DeviceState *d, Error **errp)
+{
+ ISADevice *isa = ISA_DEVICE(d);
+ HypervTestDev *dev = HYPERV_TEST_DEV(d);
+ MemoryRegion *io = isa_address_space_io(isa);
+
+ memset(dev->sint_route, 0, sizeof(dev->sint_route));
+ memory_region_init_io(&dev->sint_control, OBJECT(dev),
+ &synic_test_sint_ops, dev,
+ "hyperv-testdev-ctl", 4);
+ memory_region_add_subregion(io, 0x3000, &dev->sint_control);
+}
+
+static void hv_test_dev_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ dc->realize = hv_test_dev_realizefn;
+}
+
+static const TypeInfo hv_test_dev_info = {
+ .name = TYPE_HYPERV_TEST_DEV,
+ .parent = TYPE_ISA_DEVICE,
+ .instance_size = sizeof(HypervTestDev),
+ .class_init = hv_test_dev_class_init,
+};
+
+static void hv_test_dev_register_types(void)
+{
+ type_register_static(&hv_test_dev_info);
+}
+type_init(hv_test_dev_register_types);
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index fd1171e481..00bddc9270 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -1759,9 +1759,6 @@ void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier)
if (notifier) {
notifier_list_add(&req->cancel_notifiers, notifier);
}
- if (req->io_canceled) {
- return;
- }
scsi_req_ref(req);
scsi_req_dequeue(req);
req->io_canceled = true;
@@ -1841,11 +1838,13 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
{
SCSIRequest *req;
+ aio_context_acquire(blk_get_aio_context(sdev->conf.blk));
while (!QTAILQ_EMPTY(&sdev->requests)) {
req = QTAILQ_FIRST(&sdev->requests);
- scsi_req_cancel(req);
+ scsi_req_cancel_async(req, NULL);
}
-
+ blk_drain(sdev->conf.blk);
+ aio_context_release(blk_get_aio_context(sdev->conf.blk));
scsi_device_set_ua(sdev, sense);
}
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 9c71f31fe2..6b4b9899a4 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -32,7 +32,6 @@
#include "trace.h"
-#define PVSCSI_MSI_OFFSET (0x50)
#define PVSCSI_USE_64BIT (true)
#define PVSCSI_PER_VECTOR_MASK (false)
@@ -49,9 +48,33 @@
(stl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \
(m)->rs_pa + offsetof(struct PVSCSIRingsState, field), val))
+typedef struct PVSCSIClass {
+ PCIDeviceClass parent_class;
+ DeviceRealize parent_dc_realize;
+} PVSCSIClass;
+
#define TYPE_PVSCSI "pvscsi"
#define PVSCSI(obj) OBJECT_CHECK(PVSCSIState, (obj), TYPE_PVSCSI)
+#define PVSCSI_DEVICE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(PVSCSIClass, (klass), TYPE_PVSCSI)
+#define PVSCSI_DEVICE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(PVSCSIClass, (obj), TYPE_PVSCSI)
+
+/* Compatability flags for migration */
+#define PVSCSI_COMPAT_OLD_PCI_CONFIGURATION_BIT 0
+#define PVSCSI_COMPAT_OLD_PCI_CONFIGURATION \
+ (1 << PVSCSI_COMPAT_OLD_PCI_CONFIGURATION_BIT)
+#define PVSCSI_COMPAT_DISABLE_PCIE_BIT 1
+#define PVSCSI_COMPAT_DISABLE_PCIE \
+ (1 << PVSCSI_COMPAT_DISABLE_PCIE_BIT)
+
+#define PVSCSI_USE_OLD_PCI_CONFIGURATION(s) \
+ ((s)->compat_flags & PVSCSI_COMPAT_OLD_PCI_CONFIGURATION)
+#define PVSCSI_MSI_OFFSET(s) \
+ (PVSCSI_USE_OLD_PCI_CONFIGURATION(s) ? 0x50 : 0x7c)
+#define PVSCSI_EXP_EP_OFFSET (0x40)
+
typedef struct PVSCSIRingInfo {
uint64_t rs_pa;
uint32_t txr_len_mask;
@@ -100,6 +123,8 @@ typedef struct {
PVSCSIRingInfo rings; /* Data transfer rings manager */
uint32_t resetting; /* Reset in progress */
+
+ uint32_t compat_flags;
} PVSCSIState;
typedef struct PVSCSIRequest {
@@ -1019,7 +1044,7 @@ pvscsi_init_msi(PVSCSIState *s)
int res;
PCIDevice *d = PCI_DEVICE(s);
- res = msi_init(d, PVSCSI_MSI_OFFSET, PVSCSI_MSIX_NUM_VECTORS,
+ res = msi_init(d, PVSCSI_MSI_OFFSET(s), PVSCSI_MSIX_NUM_VECTORS,
PVSCSI_USE_64BIT, PVSCSI_PER_VECTOR_MASK);
if (res < 0) {
trace_pvscsi_init_msi_fail(res);
@@ -1069,9 +1094,16 @@ pvscsi_init(PCIDevice *pci_dev)
trace_pvscsi_state("init");
- /* PCI subsystem ID */
- pci_dev->config[PCI_SUBSYSTEM_ID] = 0x00;
- pci_dev->config[PCI_SUBSYSTEM_ID + 1] = 0x10;
+ /* PCI subsystem ID, subsystem vendor ID, revision */
+ if (PVSCSI_USE_OLD_PCI_CONFIGURATION(s)) {
+ pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, 0x1000);
+ } else {
+ pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
+ PCI_VENDOR_ID_VMWARE);
+ pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
+ PCI_DEVICE_ID_VMWARE_PVSCSI);
+ pci_config_set_revision(pci_dev->config, 0x2);
+ }
/* PCI latency timer = 255 */
pci_dev->config[PCI_LATENCY_TIMER] = 0xff;
@@ -1085,6 +1117,10 @@ pvscsi_init(PCIDevice *pci_dev)
pvscsi_init_msi(s);
+ if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus)) {
+ pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET);
+ }
+
s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);
if (!s->completion_worker) {
pvscsi_cleanup_msi(s);
@@ -1139,6 +1175,27 @@ pvscsi_post_load(void *opaque, int version_id)
return 0;
}
+static bool pvscsi_vmstate_need_pcie_device(void *opaque)
+{
+ PVSCSIState *s = PVSCSI(opaque);
+
+ return !(s->compat_flags & PVSCSI_COMPAT_DISABLE_PCIE);
+}
+
+static bool pvscsi_vmstate_test_pci_device(void *opaque, int version_id)
+{
+ return !pvscsi_vmstate_need_pcie_device(opaque);
+}
+
+static const VMStateDescription vmstate_pvscsi_pcie_device = {
+ .name = "pvscsi/pcie",
+ .needed = pvscsi_vmstate_need_pcie_device,
+ .fields = (VMStateField[]) {
+ VMSTATE_PCIE_DEVICE(parent_obj, PVSCSIState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_pvscsi = {
.name = "pvscsi",
.version_id = 0,
@@ -1146,7 +1203,9 @@ static const VMStateDescription vmstate_pvscsi = {
.pre_save = pvscsi_pre_save,
.post_load = pvscsi_post_load,
.fields = (VMStateField[]) {
- VMSTATE_PCI_DEVICE(parent_obj, PVSCSIState),
+ VMSTATE_STRUCT_TEST(parent_obj, PVSCSIState,
+ pvscsi_vmstate_test_pci_device, 0,
+ vmstate_pci_device, PCIDevice),
VMSTATE_UINT8(msi_used, PVSCSIState),
VMSTATE_UINT32(resetting, PVSCSIState),
VMSTATE_UINT64(reg_interrupt_status, PVSCSIState),
@@ -1171,18 +1230,40 @@ static const VMStateDescription vmstate_pvscsi = {
VMSTATE_UINT64(rings.filled_cmp_ptr, PVSCSIState),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (const VMStateDescription*[]) {
+ &vmstate_pvscsi_pcie_device,
+ NULL
}
};
static Property pvscsi_properties[] = {
DEFINE_PROP_UINT8("use_msg", PVSCSIState, use_msg, 1),
+ DEFINE_PROP_BIT("x-old-pci-configuration", PVSCSIState, compat_flags,
+ PVSCSI_COMPAT_OLD_PCI_CONFIGURATION_BIT, false),
+ DEFINE_PROP_BIT("x-disable-pcie", PVSCSIState, compat_flags,
+ PVSCSI_COMPAT_DISABLE_PCIE_BIT, false),
DEFINE_PROP_END_OF_LIST(),
};
+static void pvscsi_realize(DeviceState *qdev, Error **errp)
+{
+ PVSCSIClass *pvs_c = PVSCSI_DEVICE_GET_CLASS(qdev);
+ PCIDevice *pci_dev = PCI_DEVICE(qdev);
+ PVSCSIState *s = PVSCSI(qdev);
+
+ if (!(s->compat_flags & PVSCSI_COMPAT_DISABLE_PCIE)) {
+ pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
+ }
+
+ pvs_c->parent_dc_realize(qdev, errp);
+}
+
static void pvscsi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ PVSCSIClass *pvs_k = PVSCSI_DEVICE_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
k->init = pvscsi_init;
@@ -1191,6 +1272,8 @@ static void pvscsi_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_VMWARE_PVSCSI;
k->class_id = PCI_CLASS_STORAGE_SCSI;
k->subsystem_id = 0x1000;
+ pvs_k->parent_dc_realize = dc->realize;
+ dc->realize = pvscsi_realize;
dc->reset = pvscsi_reset;
dc->vmsd = &vmstate_pvscsi;
dc->props = pvscsi_properties;
@@ -1202,6 +1285,7 @@ static void pvscsi_class_init(ObjectClass *klass, void *data)
static const TypeInfo pvscsi_info = {
.name = TYPE_PVSCSI,
.parent = TYPE_PCI_DEVICE,
+ .class_size = sizeof(PVSCSIClass),
.instance_size = sizeof(PVSCSIState),
.class_init = pvscsi_class_init,
.interfaces = (InterfaceInfo[]) {
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 0f07159bb4..01f10049c1 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -159,27 +159,33 @@ typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
struct MemoryRegion {
Object parent_obj;
+
/* All fields are private - violators will be prosecuted */
- const MemoryRegionOps *ops;
+
+ /* The following fields should fit in a cache line */
+ bool romd_mode;
+ bool ram;
+ bool subpage;
+ bool readonly; /* For RAM regions */
+ bool rom_device;
+ bool flush_coalesced_mmio;
+ bool global_locking;
+ uint8_t dirty_log_mask;
+ ram_addr_t ram_addr;
+ Object *owner;
const MemoryRegionIOMMUOps *iommu_ops;
+
+ const MemoryRegionOps *ops;
void *opaque;
MemoryRegion *container;
Int128 size;
hwaddr addr;
void (*destructor)(MemoryRegion *mr);
- ram_addr_t ram_addr;
uint64_t align;
- bool subpage;
bool terminates;
- bool romd_mode;
- bool ram;
bool skip_dump;
- bool readonly; /* For RAM regions */
bool enabled;
- bool rom_device;
bool warning_printed; /* For reservations */
- bool flush_coalesced_mmio;
- bool global_locking;
uint8_t vga_logging_count;
MemoryRegion *alias;
hwaddr alias_offset;
@@ -189,7 +195,6 @@ struct MemoryRegion {
QTAILQ_ENTRY(MemoryRegion) subregions_link;
QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
const char *name;
- uint8_t dirty_log_mask;
unsigned ioeventfd_nb;
MemoryRegionIoeventfd *ioeventfds;
NotifierList iommu_notify;
@@ -518,7 +523,10 @@ uint64_t memory_region_size(MemoryRegion *mr);
*
* @mr: the memory region being queried
*/
-bool memory_region_is_ram(MemoryRegion *mr);
+static inline bool memory_region_is_ram(MemoryRegion *mr)
+{
+ return mr->ram;
+}
/**
* memory_region_is_skip_dump: check whether a memory region should not be
@@ -558,7 +566,11 @@ static inline bool memory_region_is_romd(MemoryRegion *mr)
*
* @mr: the memory region being queried
*/
-bool memory_region_is_iommu(MemoryRegion *mr);
+static inline bool memory_region_is_iommu(MemoryRegion *mr)
+{
+ return mr->iommu_ops;
+}
+
/**
* memory_region_notify_iommu: notify a change in an IOMMU translation entry.
@@ -640,7 +652,11 @@ uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr);
*
* @mr: the memory region being queried
*/
-bool memory_region_is_rom(MemoryRegion *mr);
+static inline bool memory_region_is_rom(MemoryRegion *mr)
+{
+ return mr->ram && mr->readonly;
+}
+
/**
* memory_region_get_fd: Get a file descriptor backing a RAM memory region.
@@ -656,8 +672,13 @@ int memory_region_get_fd(MemoryRegion *mr);
* memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
*
* Returns a host pointer to a RAM memory region (created with
- * memory_region_init_ram() or memory_region_init_ram_ptr()). Use with
- * care.
+ * memory_region_init_ram() or memory_region_init_ram_ptr()).
+ *
+ * Use with care; by the time this function returns, the returned pointer is
+ * not protected by RCU anymore. If the caller is not within an RCU critical
+ * section and does not hold the iothread lock, it must have other means of
+ * protecting the pointer, such as a reference to the region that includes
+ * the incoming ram_addr_t.
*
* @mr: the memory region being queried.
*/
@@ -960,7 +981,10 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
* DO NOT USE THIS FUNCTION. This is a temporary workaround while the Xen
* code is being reworked.
*/
-ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr);
+static inline ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
+{
+ return mr->ram_addr;
+}
uint64_t memory_region_get_alignment(const MemoryRegion *mr);
/**
@@ -1210,23 +1234,7 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
const uint8_t *buf, int len);
-/**
- * address_space_read: read from an address space.
- *
- * Return a MemTxResult indicating whether the operation succeeded
- * or failed (eg unassigned memory, device rejected the transaction,
- * IOMMU fault).
- *
- * @as: #AddressSpace to be accessed
- * @addr: address within that address space
- * @attrs: memory transaction attributes
- * @buf: buffer with the data transferred
- */
-MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
- uint8_t *buf, int len);
-
-/**
- * address_space_ld*: load from an address space
+/* address_space_ld*: load from an address space
* address_space_st*: store to an address space
*
* These functions perform a load or store of the byte, word,
@@ -1356,6 +1364,68 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
int is_write, hwaddr access_len);
+/* Internal functions, part of the implementation of address_space_read. */
+MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
+ MemTxAttrs attrs, uint8_t *buf,
+ int len, hwaddr addr1, hwaddr l,
+ MemoryRegion *mr);
+MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
+ MemTxAttrs attrs, uint8_t *buf, int len);
+void *qemu_get_ram_ptr(ram_addr_t addr);
+
+static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
+{
+ if (is_write) {
+ return memory_region_is_ram(mr) && !mr->readonly;
+ } else {
+ return memory_region_is_ram(mr) || memory_region_is_romd(mr);
+ }
+
+ return false;
+}
+
+/**
+ * address_space_read: read from an address space.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @attrs: memory transaction attributes
+ * @buf: buffer with the data transferred
+ */
+static inline __attribute__((__always_inline__))
+MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
+ uint8_t *buf, int len)
+{
+ MemTxResult result = MEMTX_OK;
+ hwaddr l, addr1;
+ void *ptr;
+ MemoryRegion *mr;
+
+ if (__builtin_constant_p(len)) {
+ if (len) {
+ rcu_read_lock();
+ l = len;
+ mr = address_space_translate(as, addr, &addr1, &l, false);
+ if (len == l && memory_access_is_direct(mr, false)) {
+ addr1 += memory_region_get_ram_addr(mr);
+ ptr = qemu_get_ram_ptr(addr1);
+ memcpy(buf, ptr, len);
+ } else {
+ result = address_space_read_continue(as, addr, attrs, buf, len,
+ addr1, l, mr);
+ }
+ rcu_read_unlock();
+ }
+ } else {
+ result = address_space_read_full(as, addr, attrs, buf, len);
+ }
+ return result;
+}
+
#endif
#endif
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 7115154bc1..ba4c04d202 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -73,9 +73,7 @@ ram_addr_t qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size,
MemoryRegion *mr, Error **errp);
int qemu_get_ram_fd(ram_addr_t addr);
void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
-void *qemu_get_ram_ptr(ram_addr_t addr);
void qemu_ram_free(ram_addr_t addr);
-void qemu_ram_free_from_ptr(ram_addr_t addr);
int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 5da4fb00ee..f19df9769c 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -35,6 +35,7 @@ extern MachineState *current_machine;
bool machine_usb(MachineState *machine);
bool machine_kernel_irqchip_allowed(MachineState *machine);
bool machine_kernel_irqchip_required(MachineState *machine);
+bool machine_kernel_irqchip_split(MachineState *machine);
int machine_kvm_shadow_mem(MachineState *machine);
int machine_phandle_start(MachineState *machine);
bool machine_dump_guest_core(MachineState *machine);
@@ -111,6 +112,7 @@ struct MachineState {
char *accel;
bool kernel_irqchip_allowed;
bool kernel_irqchip_required;
+ bool kernel_irqchip_split;
int kvm_shadow_mem;
char *dtb;
char *dumpdtb;
diff --git a/include/hw/compat.h b/include/hw/compat.h
index d0b1c4f1ef..bcb36ef836 100644
--- a/include/hw/compat.h
+++ b/include/hw/compat.h
@@ -7,6 +7,14 @@
.property = "scsi",\
.value = "true",\
},{\
+ .driver = "pvscsi",\
+ .property = "x-old-pci-configuration",\
+ .value = "on",\
+ },{\
+ .driver = "pvscsi",\
+ .property = "x-disable-pcie",\
+ .value = "on",\
+ },{\
.driver = "e1000",\
.property = "extra_mac_registers",\
.value = "off",\
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 854c330b66..4bf4faf050 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -20,6 +20,19 @@
#define HPET_INTCAP "hpet-intcap"
+#ifdef CONFIG_KVM
+#define kvm_pit_in_kernel() \
+ (kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
+#define kvm_pic_in_kernel() \
+ (kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
+#define kvm_ioapic_in_kernel() \
+ (kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
+#else
+#define kvm_pit_in_kernel() 0
+#define kvm_pic_in_kernel() 0
+#define kvm_ioapic_in_kernel() 0
+#endif
+
/**
* PCMachineState:
* @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling
diff --git a/include/qemu/log.h b/include/qemu/log.h
index 362cbc4e67..d837d90e77 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -28,6 +28,13 @@ static inline bool qemu_log_enabled(void)
return qemu_logfile != NULL;
}
+/* Returns true if qemu_log() will write somewhere else than stderr
+ */
+static inline bool qemu_log_separate(void)
+{
+ return qemu_logfile != NULL && qemu_logfile != stderr;
+}
+
#define CPU_LOG_TB_OUT_ASM (1 << 0)
#define CPU_LOG_TB_IN_ASM (1 << 1)
#define CPU_LOG_TB_OP (1 << 2)
@@ -41,6 +48,7 @@ static inline bool qemu_log_enabled(void)
#define LOG_GUEST_ERROR (1 << 11)
#define CPU_LOG_MMU (1 << 12)
#define CPU_LOG_TB_NOCHAIN (1 << 13)
+#define CPU_LOG_PAGE (1 << 14)
/* Returns true if a bit is set in the current loglevel mask
*/
diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
index f6d1d56375..7c7cca7f6f 100644
--- a/include/qemu/rcu.h
+++ b/include/qemu/rcu.h
@@ -88,10 +88,6 @@ static inline void rcu_read_lock(void)
ctr = atomic_read(&rcu_gp_ctr);
atomic_xchg(&p_rcu_reader->ctr, ctr);
- if (atomic_read(&p_rcu_reader->waiting)) {
- atomic_set(&p_rcu_reader->waiting, false);
- qemu_event_set(&rcu_gp_event);
- }
}
static inline void rcu_read_unlock(void)
@@ -104,7 +100,7 @@ static inline void rcu_read_unlock(void)
}
atomic_xchg(&p_rcu_reader->ctr, 0);
- if (atomic_read(&p_rcu_reader->waiting)) {
+ if (unlikely(atomic_read(&p_rcu_reader->waiting))) {
atomic_set(&p_rcu_reader->waiting, false);
qemu_event_set(&rcu_gp_event);
}
diff --git a/include/standard-headers/asm-x86/hyperv.h b/include/standard-headers/asm-x86/hyperv.h
index c37c14e018..acb119d4b6 100644
--- a/include/standard-headers/asm-x86/hyperv.h
+++ b/include/standard-headers/asm-x86/hyperv.h
@@ -257,4 +257,108 @@ typedef struct _HV_REFERENCE_TSC_PAGE {
int64_t tsc_offset;
} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
+/* Define the number of synthetic interrupt sources. */
+#define HV_SYNIC_SINT_COUNT (16)
+/* Define the expected SynIC version. */
+#define HV_SYNIC_VERSION_1 (0x1)
+
+#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SINT_MASKED (1ULL << 16)
+#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
+#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
+
+#define HV_SYNIC_STIMER_COUNT (4)
+
+/* Define synthetic interrupt controller message constants. */
+#define HV_MESSAGE_SIZE (256)
+#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
+#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
+
+/* Define hypervisor message types. */
+enum hv_message_type {
+ HVMSG_NONE = 0x00000000,
+
+ /* Memory access messages. */
+ HVMSG_UNMAPPED_GPA = 0x80000000,
+ HVMSG_GPA_INTERCEPT = 0x80000001,
+
+ /* Timer notification messages. */
+ HVMSG_TIMER_EXPIRED = 0x80000010,
+
+ /* Error messages. */
+ HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
+ HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021,
+ HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
+
+ /* Trace buffer complete messages. */
+ HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040,
+
+ /* Platform-specific processor intercept messages. */
+ HVMSG_X64_IOPORT_INTERCEPT = 0x80010000,
+ HVMSG_X64_MSR_INTERCEPT = 0x80010001,
+ HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
+ HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003,
+ HVMSG_X64_APIC_EOI = 0x80010004,
+ HVMSG_X64_LEGACY_FP_ERROR = 0x80010005
+};
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+ uint8_t asu8;
+ struct {
+ uint8_t msg_pending:1;
+ uint8_t reserved:7;
+ };
+};
+
+/* Define port identifier type. */
+union hv_port_id {
+ uint32_t asu32;
+ struct {
+ uint32_t id:24;
+ uint32_t reserved:8;
+ } u;
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+ uint32_t message_type;
+ uint8_t payload_size;
+ union hv_message_flags message_flags;
+ uint8_t reserved[2];
+ union {
+ uint64_t sender;
+ union hv_port_id port;
+ };
+};
+
+/* Define synthetic interrupt controller message format. */
+struct hv_message {
+ struct hv_message_header header;
+ union {
+ uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+ } u;
+};
+
+/* Define the synthetic interrupt message page layout. */
+struct hv_message_page {
+ struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
+};
+
+/* Define timer message payload structure. */
+struct hv_timer_message_payload {
+ uint32_t timer_index;
+ uint32_t reserved;
+ uint64_t expiration_time; /* When the timer expired */
+ uint64_t delivery_time; /* When the message was delivered */
+};
+
+#define HV_STIMER_ENABLE (1ULL << 0)
+#define HV_STIMER_PERIODIC (1ULL << 1)
+#define HV_STIMER_LAZY (1ULL << 2)
+#define HV_STIMER_AUTOENABLE (1ULL << 3)
+#define HV_STIMER_SINT(config) (uint8_t)(((config) >> 16) & 0x0F)
+
#endif
diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h
new file mode 100644
index 0000000000..354f0decf1
--- /dev/null
+++ b/include/standard-headers/linux/input-event-codes.h
@@ -0,0 +1,805 @@
+/*
+ * Input event codes
+ *
+ * *** IMPORTANT ***
+ * This file is not only included from C-code but also from devicetree source
+ * files. As such this file MUST only contain comments and defines.
+ *
+ * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef _INPUT_EVENT_CODES_H
+#define _INPUT_EVENT_CODES_H
+
+/*
+ * Device properties and quirks
+ */
+
+#define INPUT_PROP_POINTER 0x00 /* needs a pointer */
+#define INPUT_PROP_DIRECT 0x01 /* direct input devices */
+#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
+#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
+#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
+#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
+#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
+
+#define INPUT_PROP_MAX 0x1f
+#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
+
+/*
+ * Event types
+ */
+
+#define EV_SYN 0x00
+#define EV_KEY 0x01
+#define EV_REL 0x02
+#define EV_ABS 0x03
+#define EV_MSC 0x04
+#define EV_SW 0x05
+#define EV_LED 0x11
+#define EV_SND 0x12
+#define EV_REP 0x14
+#define EV_FF 0x15
+#define EV_PWR 0x16
+#define EV_FF_STATUS 0x17
+#define EV_MAX 0x1f
+#define EV_CNT (EV_MAX+1)
+
+/*
+ * Synchronization events.
+ */
+
+#define SYN_REPORT 0
+#define SYN_CONFIG 1
+#define SYN_MT_REPORT 2
+#define SYN_DROPPED 3
+#define SYN_MAX 0xf
+#define SYN_CNT (SYN_MAX+1)
+
+/*
+ * Keys and buttons
+ *
+ * Most of the keys/buttons are modeled after USB HUT 1.12
+ * (see http://www.usb.org/developers/hidpage).
+ * Abbreviations in the comments:
+ * AC - Application Control
+ * AL - Application Launch Button
+ * SC - System Control
+ */
+
+#define KEY_RESERVED 0
+#define KEY_ESC 1
+#define KEY_1 2
+#define KEY_2 3
+#define KEY_3 4
+#define KEY_4 5
+#define KEY_5 6
+#define KEY_6 7
+#define KEY_7 8
+#define KEY_8 9
+#define KEY_9 10
+#define KEY_0 11
+#define KEY_MINUS 12
+#define KEY_EQUAL 13
+#define KEY_BACKSPACE 14
+#define KEY_TAB 15
+#define KEY_Q 16
+#define KEY_W 17
+#define KEY_E 18
+#define KEY_R 19
+#define KEY_T 20
+#define KEY_Y 21
+#define KEY_U 22
+#define KEY_I 23
+#define KEY_O 24
+#define KEY_P 25
+#define KEY_LEFTBRACE 26
+#define KEY_RIGHTBRACE 27
+#define KEY_ENTER 28
+#define KEY_LEFTCTRL 29
+#define KEY_A 30
+#define KEY_S 31
+#define KEY_D 32
+#define KEY_F 33
+#define KEY_G 34
+#define KEY_H 35
+#define KEY_J 36
+#define KEY_K 37
+#define KEY_L 38
+#define KEY_SEMICOLON 39
+#define KEY_APOSTROPHE 40
+#define KEY_GRAVE 41
+#define KEY_LEFTSHIFT 42
+#define KEY_BACKSLASH 43
+#define KEY_Z 44
+#define KEY_X 45
+#define KEY_C 46
+#define KEY_V 47
+#define KEY_B 48
+#define KEY_N 49
+#define KEY_M 50
+#define KEY_COMMA 51
+#define KEY_DOT 52
+#define KEY_SLASH 53
+#define KEY_RIGHTSHIFT 54
+#define KEY_KPASTERISK 55
+#define KEY_LEFTALT 56
+#define KEY_SPACE 57
+#define KEY_CAPSLOCK 58
+#define KEY_F1 59
+#define KEY_F2 60
+#define KEY_F3 61
+#define KEY_F4 62
+#define KEY_F5 63
+#define KEY_F6 64
+#define KEY_F7 65
+#define KEY_F8 66
+#define KEY_F9 67
+#define KEY_F10 68
+#define KEY_NUMLOCK 69
+#define KEY_SCROLLLOCK 70
+#define KEY_KP7 71
+#define KEY_KP8 72
+#define KEY_KP9 73
+#define KEY_KPMINUS 74
+#define KEY_KP4 75
+#define KEY_KP5 76
+#define KEY_KP6 77
+#define KEY_KPPLUS 78
+#define KEY_KP1 79
+#define KEY_KP2 80
+#define KEY_KP3 81
+#define KEY_KP0 82
+#define KEY_KPDOT 83
+
+#define KEY_ZENKAKUHANKAKU 85
+#define KEY_102ND 86
+#define KEY_F11 87
+#define KEY_F12 88
+#define KEY_RO 89
+#define KEY_KATAKANA 90
+#define KEY_HIRAGANA 91
+#define KEY_HENKAN 92
+#define KEY_KATAKANAHIRAGANA 93
+#define KEY_MUHENKAN 94
+#define KEY_KPJPCOMMA 95
+#define KEY_KPENTER 96
+#define KEY_RIGHTCTRL 97
+#define KEY_KPSLASH 98
+#define KEY_SYSRQ 99
+#define KEY_RIGHTALT 100
+#define KEY_LINEFEED 101
+#define KEY_HOME 102
+#define KEY_UP 103
+#define KEY_PAGEUP 104
+#define KEY_LEFT 105
+#define KEY_RIGHT 106
+#define KEY_END 107
+#define KEY_DOWN 108
+#define KEY_PAGEDOWN 109
+#define KEY_INSERT 110
+#define KEY_DELETE 111
+#define KEY_MACRO 112
+#define KEY_MUTE 113
+#define KEY_VOLUMEDOWN 114
+#define KEY_VOLUMEUP 115
+#define KEY_POWER 116 /* SC System Power Down */
+#define KEY_KPEQUAL 117
+#define KEY_KPPLUSMINUS 118
+#define KEY_PAUSE 119
+#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */
+
+#define KEY_KPCOMMA 121
+#define KEY_HANGEUL 122
+#define KEY_HANGUEL KEY_HANGEUL
+#define KEY_HANJA 123
+#define KEY_YEN 124
+#define KEY_LEFTMETA 125
+#define KEY_RIGHTMETA 126
+#define KEY_COMPOSE 127
+
+#define KEY_STOP 128 /* AC Stop */
+#define KEY_AGAIN 129
+#define KEY_PROPS 130 /* AC Properties */
+#define KEY_UNDO 131 /* AC Undo */
+#define KEY_FRONT 132
+#define KEY_COPY 133 /* AC Copy */
+#define KEY_OPEN 134 /* AC Open */
+#define KEY_PASTE 135 /* AC Paste */
+#define KEY_FIND 136 /* AC Search */
+#define KEY_CUT 137 /* AC Cut */
+#define KEY_HELP 138 /* AL Integrated Help Center */
+#define KEY_MENU 139 /* Menu (show menu) */
+#define KEY_CALC 140 /* AL Calculator */
+#define KEY_SETUP 141
+#define KEY_SLEEP 142 /* SC System Sleep */
+#define KEY_WAKEUP 143 /* System Wake Up */
+#define KEY_FILE 144 /* AL Local Machine Browser */
+#define KEY_SENDFILE 145
+#define KEY_DELETEFILE 146
+#define KEY_XFER 147
+#define KEY_PROG1 148
+#define KEY_PROG2 149
+#define KEY_WWW 150 /* AL Internet Browser */
+#define KEY_MSDOS 151
+#define KEY_COFFEE 152 /* AL Terminal Lock/Screensaver */
+#define KEY_SCREENLOCK KEY_COFFEE
+#define KEY_ROTATE_DISPLAY 153 /* Display orientation for e.g. tablets */
+#define KEY_DIRECTION KEY_ROTATE_DISPLAY
+#define KEY_CYCLEWINDOWS 154
+#define KEY_MAIL 155
+#define KEY_BOOKMARKS 156 /* AC Bookmarks */
+#define KEY_COMPUTER 157
+#define KEY_BACK 158 /* AC Back */
+#define KEY_FORWARD 159 /* AC Forward */
+#define KEY_CLOSECD 160
+#define KEY_EJECTCD 161
+#define KEY_EJECTCLOSECD 162
+#define KEY_NEXTSONG 163
+#define KEY_PLAYPAUSE 164
+#define KEY_PREVIOUSSONG 165
+#define KEY_STOPCD 166
+#define KEY_RECORD 167
+#define KEY_REWIND 168
+#define KEY_PHONE 169 /* Media Select Telephone */
+#define KEY_ISO 170
+#define KEY_CONFIG 171 /* AL Consumer Control Configuration */
+#define KEY_HOMEPAGE 172 /* AC Home */
+#define KEY_REFRESH 173 /* AC Refresh */
+#define KEY_EXIT 174 /* AC Exit */
+#define KEY_MOVE 175
+#define KEY_EDIT 176
+#define KEY_SCROLLUP 177
+#define KEY_SCROLLDOWN 178
+#define KEY_KPLEFTPAREN 179
+#define KEY_KPRIGHTPAREN 180
+#define KEY_NEW 181 /* AC New */
+#define KEY_REDO 182 /* AC Redo/Repeat */
+
+#define KEY_F13 183
+#define KEY_F14 184
+#define KEY_F15 185
+#define KEY_F16 186
+#define KEY_F17 187
+#define KEY_F18 188
+#define KEY_F19 189
+#define KEY_F20 190
+#define KEY_F21 191
+#define KEY_F22 192
+#define KEY_F23 193
+#define KEY_F24 194
+
+#define KEY_PLAYCD 200
+#define KEY_PAUSECD 201
+#define KEY_PROG3 202
+#define KEY_PROG4 203
+#define KEY_DASHBOARD 204 /* AL Dashboard */
+#define KEY_SUSPEND 205
+#define KEY_CLOSE 206 /* AC Close */
+#define KEY_PLAY 207
+#define KEY_FASTFORWARD 208
+#define KEY_BASSBOOST 209
+#define KEY_PRINT 210 /* AC Print */
+#define KEY_HP 211
+#define KEY_CAMERA 212
+#define KEY_SOUND 213
+#define KEY_QUESTION 214
+#define KEY_EMAIL 215
+#define KEY_CHAT 216
+#define KEY_SEARCH 217
+#define KEY_CONNECT 218
+#define KEY_FINANCE 219 /* AL Checkbook/Finance */
+#define KEY_SPORT 220
+#define KEY_SHOP 221
+#define KEY_ALTERASE 222
+#define KEY_CANCEL 223 /* AC Cancel */
+#define KEY_BRIGHTNESSDOWN 224
+#define KEY_BRIGHTNESSUP 225
+#define KEY_MEDIA 226
+
+#define KEY_SWITCHVIDEOMODE 227 /* Cycle between available video
+ outputs (Monitor/LCD/TV-out/etc) */
+#define KEY_KBDILLUMTOGGLE 228
+#define KEY_KBDILLUMDOWN 229
+#define KEY_KBDILLUMUP 230
+
+#define KEY_SEND 231 /* AC Send */
+#define KEY_REPLY 232 /* AC Reply */
+#define KEY_FORWARDMAIL 233 /* AC Forward Msg */
+#define KEY_SAVE 234 /* AC Save */
+#define KEY_DOCUMENTS 235
+
+#define KEY_BATTERY 236
+
+#define KEY_BLUETOOTH 237
+#define KEY_WLAN 238
+#define KEY_UWB 239
+
+#define KEY_UNKNOWN 240
+
+#define KEY_VIDEO_NEXT 241 /* drive next video source */
+#define KEY_VIDEO_PREV 242 /* drive previous video source */
+#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */
+#define KEY_BRIGHTNESS_AUTO 244 /* Set Auto Brightness: manual
+ brightness control is off,
+ rely on ambient */
+#define KEY_BRIGHTNESS_ZERO KEY_BRIGHTNESS_AUTO
+#define KEY_DISPLAY_OFF 245 /* display device to off state */
+
+#define KEY_WWAN 246 /* Wireless WAN (LTE, UMTS, GSM, etc.) */
+#define KEY_WIMAX KEY_WWAN
+#define KEY_RFKILL 247 /* Key that controls all radios */
+
+#define KEY_MICMUTE 248 /* Mute / unmute the microphone */
+
+/* Code 255 is reserved for special needs of AT keyboard driver */
+
+#define BTN_MISC 0x100
+#define BTN_0 0x100
+#define BTN_1 0x101
+#define BTN_2 0x102
+#define BTN_3 0x103
+#define BTN_4 0x104
+#define BTN_5 0x105
+#define BTN_6 0x106
+#define BTN_7 0x107
+#define BTN_8 0x108
+#define BTN_9 0x109
+
+#define BTN_MOUSE 0x110
+#define BTN_LEFT 0x110
+#define BTN_RIGHT 0x111
+#define BTN_MIDDLE 0x112
+#define BTN_SIDE 0x113
+#define BTN_EXTRA 0x114
+#define BTN_FORWARD 0x115
+#define BTN_BACK 0x116
+#define BTN_TASK 0x117
+
+#define BTN_JOYSTICK 0x120
+#define BTN_TRIGGER 0x120
+#define BTN_THUMB 0x121
+#define BTN_THUMB2 0x122
+#define BTN_TOP 0x123
+#define BTN_TOP2 0x124
+#define BTN_PINKIE 0x125
+#define BTN_BASE 0x126
+#define BTN_BASE2 0x127
+#define BTN_BASE3 0x128
+#define BTN_BASE4 0x129
+#define BTN_BASE5 0x12a
+#define BTN_BASE6 0x12b
+#define BTN_DEAD 0x12f
+
+#define BTN_GAMEPAD 0x130
+#define BTN_SOUTH 0x130
+#define BTN_A BTN_SOUTH
+#define BTN_EAST 0x131
+#define BTN_B BTN_EAST
+#define BTN_C 0x132
+#define BTN_NORTH 0x133
+#define BTN_X BTN_NORTH
+#define BTN_WEST 0x134
+#define BTN_Y BTN_WEST
+#define BTN_Z 0x135
+#define BTN_TL 0x136
+#define BTN_TR 0x137
+#define BTN_TL2 0x138
+#define BTN_TR2 0x139
+#define BTN_SELECT 0x13a
+#define BTN_START 0x13b
+#define BTN_MODE 0x13c
+#define BTN_THUMBL 0x13d
+#define BTN_THUMBR 0x13e
+
+#define BTN_DIGI 0x140
+#define BTN_TOOL_PEN 0x140
+#define BTN_TOOL_RUBBER 0x141
+#define BTN_TOOL_BRUSH 0x142
+#define BTN_TOOL_PENCIL 0x143
+#define BTN_TOOL_AIRBRUSH 0x144
+#define BTN_TOOL_FINGER 0x145
+#define BTN_TOOL_MOUSE 0x146
+#define BTN_TOOL_LENS 0x147
+#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */
+#define BTN_TOUCH 0x14a
+#define BTN_STYLUS 0x14b
+#define BTN_STYLUS2 0x14c
+#define BTN_TOOL_DOUBLETAP 0x14d
+#define BTN_TOOL_TRIPLETAP 0x14e
+#define BTN_TOOL_QUADTAP 0x14f /* Four fingers on trackpad */
+
+#define BTN_WHEEL 0x150
+#define BTN_GEAR_DOWN 0x150
+#define BTN_GEAR_UP 0x151
+
+#define KEY_OK 0x160
+#define KEY_SELECT 0x161
+#define KEY_GOTO 0x162
+#define KEY_CLEAR 0x163
+#define KEY_POWER2 0x164
+#define KEY_OPTION 0x165
+#define KEY_INFO 0x166 /* AL OEM Features/Tips/Tutorial */
+#define KEY_TIME 0x167
+#define KEY_VENDOR 0x168
+#define KEY_ARCHIVE 0x169
+#define KEY_PROGRAM 0x16a /* Media Select Program Guide */
+#define KEY_CHANNEL 0x16b
+#define KEY_FAVORITES 0x16c
+#define KEY_EPG 0x16d
+#define KEY_PVR 0x16e /* Media Select Home */
+#define KEY_MHP 0x16f
+#define KEY_LANGUAGE 0x170
+#define KEY_TITLE 0x171
+#define KEY_SUBTITLE 0x172
+#define KEY_ANGLE 0x173
+#define KEY_ZOOM 0x174
+#define KEY_MODE 0x175
+#define KEY_KEYBOARD 0x176
+#define KEY_SCREEN 0x177
+#define KEY_PC 0x178 /* Media Select Computer */
+#define KEY_TV 0x179 /* Media Select TV */
+#define KEY_TV2 0x17a /* Media Select Cable */
+#define KEY_VCR 0x17b /* Media Select VCR */
+#define KEY_VCR2 0x17c /* VCR Plus */
+#define KEY_SAT 0x17d /* Media Select Satellite */
+#define KEY_SAT2 0x17e
+#define KEY_CD 0x17f /* Media Select CD */
+#define KEY_TAPE 0x180 /* Media Select Tape */
+#define KEY_RADIO 0x181
+#define KEY_TUNER 0x182 /* Media Select Tuner */
+#define KEY_PLAYER 0x183
+#define KEY_TEXT 0x184
+#define KEY_DVD 0x185 /* Media Select DVD */
+#define KEY_AUX 0x186
+#define KEY_MP3 0x187
+#define KEY_AUDIO 0x188 /* AL Audio Browser */
+#define KEY_VIDEO 0x189 /* AL Movie Browser */
+#define KEY_DIRECTORY 0x18a
+#define KEY_LIST 0x18b
+#define KEY_MEMO 0x18c /* Media Select Messages */
+#define KEY_CALENDAR 0x18d
+#define KEY_RED 0x18e
+#define KEY_GREEN 0x18f
+#define KEY_YELLOW 0x190
+#define KEY_BLUE 0x191
+#define KEY_CHANNELUP 0x192 /* Channel Increment */
+#define KEY_CHANNELDOWN 0x193 /* Channel Decrement */
+#define KEY_FIRST 0x194
+#define KEY_LAST 0x195 /* Recall Last */
+#define KEY_AB 0x196
+#define KEY_NEXT 0x197
+#define KEY_RESTART 0x198
+#define KEY_SLOW 0x199
+#define KEY_SHUFFLE 0x19a
+#define KEY_BREAK 0x19b
+#define KEY_PREVIOUS 0x19c
+#define KEY_DIGITS 0x19d
+#define KEY_TEEN 0x19e
+#define KEY_TWEN 0x19f
+#define KEY_VIDEOPHONE 0x1a0 /* Media Select Video Phone */
+#define KEY_GAMES 0x1a1 /* Media Select Games */
+#define KEY_ZOOMIN 0x1a2 /* AC Zoom In */
+#define KEY_ZOOMOUT 0x1a3 /* AC Zoom Out */
+#define KEY_ZOOMRESET 0x1a4 /* AC Zoom */
+#define KEY_WORDPROCESSOR 0x1a5 /* AL Word Processor */
+#define KEY_EDITOR 0x1a6 /* AL Text Editor */
+#define KEY_SPREADSHEET 0x1a7 /* AL Spreadsheet */
+#define KEY_GRAPHICSEDITOR 0x1a8 /* AL Graphics Editor */
+#define KEY_PRESENTATION 0x1a9 /* AL Presentation App */
+#define KEY_DATABASE 0x1aa /* AL Database App */
+#define KEY_NEWS 0x1ab /* AL Newsreader */
+#define KEY_VOICEMAIL 0x1ac /* AL Voicemail */
+#define KEY_ADDRESSBOOK 0x1ad /* AL Contacts/Address Book */
+#define KEY_MESSENGER 0x1ae /* AL Instant Messaging */
+#define KEY_DISPLAYTOGGLE 0x1af /* Turn display (LCD) on and off */
+#define KEY_BRIGHTNESS_TOGGLE KEY_DISPLAYTOGGLE
+#define KEY_SPELLCHECK 0x1b0 /* AL Spell Check */
+#define KEY_LOGOFF 0x1b1 /* AL Logoff */
+
+#define KEY_DOLLAR 0x1b2
+#define KEY_EURO 0x1b3
+
+#define KEY_FRAMEBACK 0x1b4 /* Consumer - transport controls */
+#define KEY_FRAMEFORWARD 0x1b5
+#define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */
+#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
+#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
+#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
+#define KEY_IMAGES 0x1ba /* AL Image Browser */
+
+#define KEY_DEL_EOL 0x1c0
+#define KEY_DEL_EOS 0x1c1
+#define KEY_INS_LINE 0x1c2
+#define KEY_DEL_LINE 0x1c3
+
+#define KEY_FN 0x1d0
+#define KEY_FN_ESC 0x1d1
+#define KEY_FN_F1 0x1d2
+#define KEY_FN_F2 0x1d3
+#define KEY_FN_F3 0x1d4
+#define KEY_FN_F4 0x1d5
+#define KEY_FN_F5 0x1d6
+#define KEY_FN_F6 0x1d7
+#define KEY_FN_F7 0x1d8
+#define KEY_FN_F8 0x1d9
+#define KEY_FN_F9 0x1da
+#define KEY_FN_F10 0x1db
+#define KEY_FN_F11 0x1dc
+#define KEY_FN_F12 0x1dd
+#define KEY_FN_1 0x1de
+#define KEY_FN_2 0x1df
+#define KEY_FN_D 0x1e0
+#define KEY_FN_E 0x1e1
+#define KEY_FN_F 0x1e2
+#define KEY_FN_S 0x1e3
+#define KEY_FN_B 0x1e4
+
+#define KEY_BRL_DOT1 0x1f1
+#define KEY_BRL_DOT2 0x1f2
+#define KEY_BRL_DOT3 0x1f3
+#define KEY_BRL_DOT4 0x1f4
+#define KEY_BRL_DOT5 0x1f5
+#define KEY_BRL_DOT6 0x1f6
+#define KEY_BRL_DOT7 0x1f7
+#define KEY_BRL_DOT8 0x1f8
+#define KEY_BRL_DOT9 0x1f9
+#define KEY_BRL_DOT10 0x1fa
+
+#define KEY_NUMERIC_0 0x200 /* used by phones, remote controls, */
+#define KEY_NUMERIC_1 0x201 /* and other keypads */
+#define KEY_NUMERIC_2 0x202
+#define KEY_NUMERIC_3 0x203
+#define KEY_NUMERIC_4 0x204
+#define KEY_NUMERIC_5 0x205
+#define KEY_NUMERIC_6 0x206
+#define KEY_NUMERIC_7 0x207
+#define KEY_NUMERIC_8 0x208
+#define KEY_NUMERIC_9 0x209
+#define KEY_NUMERIC_STAR 0x20a
+#define KEY_NUMERIC_POUND 0x20b
+#define KEY_NUMERIC_A 0x20c /* Phone key A - HUT Telephony 0xb9 */
+#define KEY_NUMERIC_B 0x20d
+#define KEY_NUMERIC_C 0x20e
+#define KEY_NUMERIC_D 0x20f
+
+#define KEY_CAMERA_FOCUS 0x210
+#define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */
+
+#define KEY_TOUCHPAD_TOGGLE 0x212 /* Request switch touchpad on or off */
+#define KEY_TOUCHPAD_ON 0x213
+#define KEY_TOUCHPAD_OFF 0x214
+
+#define KEY_CAMERA_ZOOMIN 0x215
+#define KEY_CAMERA_ZOOMOUT 0x216
+#define KEY_CAMERA_UP 0x217
+#define KEY_CAMERA_DOWN 0x218
+#define KEY_CAMERA_LEFT 0x219
+#define KEY_CAMERA_RIGHT 0x21a
+
+#define KEY_ATTENDANT_ON 0x21b
+#define KEY_ATTENDANT_OFF 0x21c
+#define KEY_ATTENDANT_TOGGLE 0x21d /* Attendant call on or off */
+#define KEY_LIGHTS_TOGGLE 0x21e /* Reading light on or off */
+
+#define BTN_DPAD_UP 0x220
+#define BTN_DPAD_DOWN 0x221
+#define BTN_DPAD_LEFT 0x222
+#define BTN_DPAD_RIGHT 0x223
+
+#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
+
+#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
+#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
+#define KEY_JOURNAL 0x242 /* AL Log/Journal/Timecard */
+#define KEY_CONTROLPANEL 0x243 /* AL Control Panel */
+#define KEY_APPSELECT 0x244 /* AL Select Task/Application */
+#define KEY_SCREENSAVER 0x245 /* AL Screen Saver */
+#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
+
+#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
+#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
+
+#define KEY_KBDINPUTASSIST_PREV 0x260
+#define KEY_KBDINPUTASSIST_NEXT 0x261
+#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
+#define KEY_KBDINPUTASSIST_NEXTGROUP 0x263
+#define KEY_KBDINPUTASSIST_ACCEPT 0x264
+#define KEY_KBDINPUTASSIST_CANCEL 0x265
+
+#define BTN_TRIGGER_HAPPY 0x2c0
+#define BTN_TRIGGER_HAPPY1 0x2c0
+#define BTN_TRIGGER_HAPPY2 0x2c1
+#define BTN_TRIGGER_HAPPY3 0x2c2
+#define BTN_TRIGGER_HAPPY4 0x2c3
+#define BTN_TRIGGER_HAPPY5 0x2c4
+#define BTN_TRIGGER_HAPPY6 0x2c5
+#define BTN_TRIGGER_HAPPY7 0x2c6
+#define BTN_TRIGGER_HAPPY8 0x2c7
+#define BTN_TRIGGER_HAPPY9 0x2c8
+#define BTN_TRIGGER_HAPPY10 0x2c9
+#define BTN_TRIGGER_HAPPY11 0x2ca
+#define BTN_TRIGGER_HAPPY12 0x2cb
+#define BTN_TRIGGER_HAPPY13 0x2cc
+#define BTN_TRIGGER_HAPPY14 0x2cd
+#define BTN_TRIGGER_HAPPY15 0x2ce
+#define BTN_TRIGGER_HAPPY16 0x2cf
+#define BTN_TRIGGER_HAPPY17 0x2d0
+#define BTN_TRIGGER_HAPPY18 0x2d1
+#define BTN_TRIGGER_HAPPY19 0x2d2
+#define BTN_TRIGGER_HAPPY20 0x2d3
+#define BTN_TRIGGER_HAPPY21 0x2d4
+#define BTN_TRIGGER_HAPPY22 0x2d5
+#define BTN_TRIGGER_HAPPY23 0x2d6
+#define BTN_TRIGGER_HAPPY24 0x2d7
+#define BTN_TRIGGER_HAPPY25 0x2d8
+#define BTN_TRIGGER_HAPPY26 0x2d9
+#define BTN_TRIGGER_HAPPY27 0x2da
+#define BTN_TRIGGER_HAPPY28 0x2db
+#define BTN_TRIGGER_HAPPY29 0x2dc
+#define BTN_TRIGGER_HAPPY30 0x2dd
+#define BTN_TRIGGER_HAPPY31 0x2de
+#define BTN_TRIGGER_HAPPY32 0x2df
+#define BTN_TRIGGER_HAPPY33 0x2e0
+#define BTN_TRIGGER_HAPPY34 0x2e1
+#define BTN_TRIGGER_HAPPY35 0x2e2
+#define BTN_TRIGGER_HAPPY36 0x2e3
+#define BTN_TRIGGER_HAPPY37 0x2e4
+#define BTN_TRIGGER_HAPPY38 0x2e5
+#define BTN_TRIGGER_HAPPY39 0x2e6
+#define BTN_TRIGGER_HAPPY40 0x2e7
+
+/* We avoid low common keys in module aliases so they don't get huge. */
+#define KEY_MIN_INTERESTING KEY_MUTE
+#define KEY_MAX 0x2ff
+#define KEY_CNT (KEY_MAX+1)
+
+/*
+ * Relative axes
+ */
+
+#define REL_X 0x00
+#define REL_Y 0x01
+#define REL_Z 0x02
+#define REL_RX 0x03
+#define REL_RY 0x04
+#define REL_RZ 0x05
+#define REL_HWHEEL 0x06
+#define REL_DIAL 0x07
+#define REL_WHEEL 0x08
+#define REL_MISC 0x09
+#define REL_MAX 0x0f
+#define REL_CNT (REL_MAX+1)
+
+/*
+ * Absolute axes
+ */
+
+#define ABS_X 0x00
+#define ABS_Y 0x01
+#define ABS_Z 0x02
+#define ABS_RX 0x03
+#define ABS_RY 0x04
+#define ABS_RZ 0x05
+#define ABS_THROTTLE 0x06
+#define ABS_RUDDER 0x07
+#define ABS_WHEEL 0x08
+#define ABS_GAS 0x09
+#define ABS_BRAKE 0x0a
+#define ABS_HAT0X 0x10
+#define ABS_HAT0Y 0x11
+#define ABS_HAT1X 0x12
+#define ABS_HAT1Y 0x13
+#define ABS_HAT2X 0x14
+#define ABS_HAT2Y 0x15
+#define ABS_HAT3X 0x16
+#define ABS_HAT3Y 0x17
+#define ABS_PRESSURE 0x18
+#define ABS_DISTANCE 0x19
+#define ABS_TILT_X 0x1a
+#define ABS_TILT_Y 0x1b
+#define ABS_TOOL_WIDTH 0x1c
+
+#define ABS_VOLUME 0x20
+
+#define ABS_MISC 0x28
+
+#define ABS_MT_SLOT 0x2f /* MT slot being modified */
+#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
+#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
+#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
+#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
+#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
+#define ABS_MT_POSITION_X 0x35 /* Center X touch position */
+#define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */
+#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
+#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
+#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
+#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
+#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */
+#define ABS_MT_TOOL_X 0x3c /* Center X tool position */
+#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
+
+
+#define ABS_MAX 0x3f
+#define ABS_CNT (ABS_MAX+1)
+
+/*
+ * Switch events
+ */
+
+#define SW_LID 0x00 /* set = lid shut */
+#define SW_TABLET_MODE 0x01 /* set = tablet mode */
+#define SW_HEADPHONE_INSERT 0x02 /* set = inserted */
+#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any"
+ set = radio enabled */
+#define SW_RADIO SW_RFKILL_ALL /* deprecated */
+#define SW_MICROPHONE_INSERT 0x04 /* set = inserted */
+#define SW_DOCK 0x05 /* set = plugged into dock */
+#define SW_LINEOUT_INSERT 0x06 /* set = inserted */
+#define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */
+#define SW_VIDEOOUT_INSERT 0x08 /* set = inserted */
+#define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */
+#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */
+#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
+#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
+#define SW_LINEIN_INSERT 0x0d /* set = inserted */
+#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
+#define SW_MAX_ 0x0f
+#define SW_CNT (SW_MAX_+1)
+
+/*
+ * Misc events
+ */
+
+#define MSC_SERIAL 0x00
+#define MSC_PULSELED 0x01
+#define MSC_GESTURE 0x02
+#define MSC_RAW 0x03
+#define MSC_SCAN 0x04
+#define MSC_TIMESTAMP 0x05
+#define MSC_MAX 0x07
+#define MSC_CNT (MSC_MAX+1)
+
+/*
+ * LEDs
+ */
+
+#define LED_NUML 0x00
+#define LED_CAPSL 0x01
+#define LED_SCROLLL 0x02
+#define LED_COMPOSE 0x03
+#define LED_KANA 0x04
+#define LED_SLEEP 0x05
+#define LED_SUSPEND 0x06
+#define LED_MUTE 0x07
+#define LED_MISC 0x08
+#define LED_MAIL 0x09
+#define LED_CHARGING 0x0a
+#define LED_MAX 0x0f
+#define LED_CNT (LED_MAX+1)
+
+/*
+ * Autorepeat values
+ */
+
+#define REP_DELAY 0x00
+#define REP_PERIOD 0x01
+#define REP_MAX 0x01
+#define REP_CNT (REP_MAX+1)
+
+/*
+ * Sounds
+ */
+
+#define SND_CLICK 0x00
+#define SND_BELL 0x01
+#define SND_TONE 0x02
+#define SND_MAX 0x07
+#define SND_CNT (SND_MAX+1)
+
+#endif
diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h
index 43f1850b6b..8b2c928e0d 100644
--- a/include/standard-headers/linux/input.h
+++ b/include/standard-headers/linux/input.h
@@ -13,6 +13,7 @@
#include <sys/types.h>
#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/input-event-codes.h"
/*
* The event structure itself
@@ -94,6 +95,12 @@ struct input_keymap_entry {
uint8_t scancode[32];
};
+struct input_mask {
+ uint32_t type;
+ uint32_t codes_size;
+ uint64_t codes_ptr;
+};
+
#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
#define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */
@@ -144,801 +151,68 @@ struct input_keymap_entry {
#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) /* get abs value/limits */
#define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo) /* set abs value/limits */
-#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */
+#define EVIOCSFF _IOW('E', 0x80, struct ff_effect) /* send a force effect to a force feedback device */
#define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */
#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
#define EVIOCREVOKE _IOW('E', 0x91, int) /* Revoke device access */
-#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
-
-/*
- * Device properties and quirks
- */
-
-#define INPUT_PROP_POINTER 0x00 /* needs a pointer */
-#define INPUT_PROP_DIRECT 0x01 /* direct input devices */
-#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
-#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
-#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
-#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
-#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
-
-#define INPUT_PROP_MAX 0x1f
-#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
-
-/*
- * Event types
- */
-
-#define EV_SYN 0x00
-#define EV_KEY 0x01
-#define EV_REL 0x02
-#define EV_ABS 0x03
-#define EV_MSC 0x04
-#define EV_SW 0x05
-#define EV_LED 0x11
-#define EV_SND 0x12
-#define EV_REP 0x14
-#define EV_FF 0x15
-#define EV_PWR 0x16
-#define EV_FF_STATUS 0x17
-#define EV_MAX 0x1f
-#define EV_CNT (EV_MAX+1)
-
-/*
- * Synchronization events.
- */
-
-#define SYN_REPORT 0
-#define SYN_CONFIG 1
-#define SYN_MT_REPORT 2
-#define SYN_DROPPED 3
-#define SYN_MAX 0xf
-#define SYN_CNT (SYN_MAX+1)
-
-/*
- * Keys and buttons
+/**
+ * EVIOCGMASK - Retrieve current event mask
*
- * Most of the keys/buttons are modeled after USB HUT 1.12
- * (see http://www.usb.org/developers/hidpage).
- * Abbreviations in the comments:
- * AC - Application Control
- * AL - Application Launch Button
- * SC - System Control
- */
-
-#define KEY_RESERVED 0
-#define KEY_ESC 1
-#define KEY_1 2
-#define KEY_2 3
-#define KEY_3 4
-#define KEY_4 5
-#define KEY_5 6
-#define KEY_6 7
-#define KEY_7 8
-#define KEY_8 9
-#define KEY_9 10
-#define KEY_0 11
-#define KEY_MINUS 12
-#define KEY_EQUAL 13
-#define KEY_BACKSPACE 14
-#define KEY_TAB 15
-#define KEY_Q 16
-#define KEY_W 17
-#define KEY_E 18
-#define KEY_R 19
-#define KEY_T 20
-#define KEY_Y 21
-#define KEY_U 22
-#define KEY_I 23
-#define KEY_O 24
-#define KEY_P 25
-#define KEY_LEFTBRACE 26
-#define KEY_RIGHTBRACE 27
-#define KEY_ENTER 28
-#define KEY_LEFTCTRL 29
-#define KEY_A 30
-#define KEY_S 31
-#define KEY_D 32
-#define KEY_F 33
-#define KEY_G 34
-#define KEY_H 35
-#define KEY_J 36
-#define KEY_K 37
-#define KEY_L 38
-#define KEY_SEMICOLON 39
-#define KEY_APOSTROPHE 40
-#define KEY_GRAVE 41
-#define KEY_LEFTSHIFT 42
-#define KEY_BACKSLASH 43
-#define KEY_Z 44
-#define KEY_X 45
-#define KEY_C 46
-#define KEY_V 47
-#define KEY_B 48
-#define KEY_N 49
-#define KEY_M 50
-#define KEY_COMMA 51
-#define KEY_DOT 52
-#define KEY_SLASH 53
-#define KEY_RIGHTSHIFT 54
-#define KEY_KPASTERISK 55
-#define KEY_LEFTALT 56
-#define KEY_SPACE 57
-#define KEY_CAPSLOCK 58
-#define KEY_F1 59
-#define KEY_F2 60
-#define KEY_F3 61
-#define KEY_F4 62
-#define KEY_F5 63
-#define KEY_F6 64
-#define KEY_F7 65
-#define KEY_F8 66
-#define KEY_F9 67
-#define KEY_F10 68
-#define KEY_NUMLOCK 69
-#define KEY_SCROLLLOCK 70
-#define KEY_KP7 71
-#define KEY_KP8 72
-#define KEY_KP9 73
-#define KEY_KPMINUS 74
-#define KEY_KP4 75
-#define KEY_KP5 76
-#define KEY_KP6 77
-#define KEY_KPPLUS 78
-#define KEY_KP1 79
-#define KEY_KP2 80
-#define KEY_KP3 81
-#define KEY_KP0 82
-#define KEY_KPDOT 83
-
-#define KEY_ZENKAKUHANKAKU 85
-#define KEY_102ND 86
-#define KEY_F11 87
-#define KEY_F12 88
-#define KEY_RO 89
-#define KEY_KATAKANA 90
-#define KEY_HIRAGANA 91
-#define KEY_HENKAN 92
-#define KEY_KATAKANAHIRAGANA 93
-#define KEY_MUHENKAN 94
-#define KEY_KPJPCOMMA 95
-#define KEY_KPENTER 96
-#define KEY_RIGHTCTRL 97
-#define KEY_KPSLASH 98
-#define KEY_SYSRQ 99
-#define KEY_RIGHTALT 100
-#define KEY_LINEFEED 101
-#define KEY_HOME 102
-#define KEY_UP 103
-#define KEY_PAGEUP 104
-#define KEY_LEFT 105
-#define KEY_RIGHT 106
-#define KEY_END 107
-#define KEY_DOWN 108
-#define KEY_PAGEDOWN 109
-#define KEY_INSERT 110
-#define KEY_DELETE 111
-#define KEY_MACRO 112
-#define KEY_MUTE 113
-#define KEY_VOLUMEDOWN 114
-#define KEY_VOLUMEUP 115
-#define KEY_POWER 116 /* SC System Power Down */
-#define KEY_KPEQUAL 117
-#define KEY_KPPLUSMINUS 118
-#define KEY_PAUSE 119
-#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */
-
-#define KEY_KPCOMMA 121
-#define KEY_HANGEUL 122
-#define KEY_HANGUEL KEY_HANGEUL
-#define KEY_HANJA 123
-#define KEY_YEN 124
-#define KEY_LEFTMETA 125
-#define KEY_RIGHTMETA 126
-#define KEY_COMPOSE 127
-
-#define KEY_STOP 128 /* AC Stop */
-#define KEY_AGAIN 129
-#define KEY_PROPS 130 /* AC Properties */
-#define KEY_UNDO 131 /* AC Undo */
-#define KEY_FRONT 132
-#define KEY_COPY 133 /* AC Copy */
-#define KEY_OPEN 134 /* AC Open */
-#define KEY_PASTE 135 /* AC Paste */
-#define KEY_FIND 136 /* AC Search */
-#define KEY_CUT 137 /* AC Cut */
-#define KEY_HELP 138 /* AL Integrated Help Center */
-#define KEY_MENU 139 /* Menu (show menu) */
-#define KEY_CALC 140 /* AL Calculator */
-#define KEY_SETUP 141
-#define KEY_SLEEP 142 /* SC System Sleep */
-#define KEY_WAKEUP 143 /* System Wake Up */
-#define KEY_FILE 144 /* AL Local Machine Browser */
-#define KEY_SENDFILE 145
-#define KEY_DELETEFILE 146
-#define KEY_XFER 147
-#define KEY_PROG1 148
-#define KEY_PROG2 149
-#define KEY_WWW 150 /* AL Internet Browser */
-#define KEY_MSDOS 151
-#define KEY_COFFEE 152 /* AL Terminal Lock/Screensaver */
-#define KEY_SCREENLOCK KEY_COFFEE
-#define KEY_ROTATE_DISPLAY 153 /* Display orientation for e.g. tablets */
-#define KEY_DIRECTION KEY_ROTATE_DISPLAY
-#define KEY_CYCLEWINDOWS 154
-#define KEY_MAIL 155
-#define KEY_BOOKMARKS 156 /* AC Bookmarks */
-#define KEY_COMPUTER 157
-#define KEY_BACK 158 /* AC Back */
-#define KEY_FORWARD 159 /* AC Forward */
-#define KEY_CLOSECD 160
-#define KEY_EJECTCD 161
-#define KEY_EJECTCLOSECD 162
-#define KEY_NEXTSONG 163
-#define KEY_PLAYPAUSE 164
-#define KEY_PREVIOUSSONG 165
-#define KEY_STOPCD 166
-#define KEY_RECORD 167
-#define KEY_REWIND 168
-#define KEY_PHONE 169 /* Media Select Telephone */
-#define KEY_ISO 170
-#define KEY_CONFIG 171 /* AL Consumer Control Configuration */
-#define KEY_HOMEPAGE 172 /* AC Home */
-#define KEY_REFRESH 173 /* AC Refresh */
-#define KEY_EXIT 174 /* AC Exit */
-#define KEY_MOVE 175
-#define KEY_EDIT 176
-#define KEY_SCROLLUP 177
-#define KEY_SCROLLDOWN 178
-#define KEY_KPLEFTPAREN 179
-#define KEY_KPRIGHTPAREN 180
-#define KEY_NEW 181 /* AC New */
-#define KEY_REDO 182 /* AC Redo/Repeat */
-
-#define KEY_F13 183
-#define KEY_F14 184
-#define KEY_F15 185
-#define KEY_F16 186
-#define KEY_F17 187
-#define KEY_F18 188
-#define KEY_F19 189
-#define KEY_F20 190
-#define KEY_F21 191
-#define KEY_F22 192
-#define KEY_F23 193
-#define KEY_F24 194
-
-#define KEY_PLAYCD 200
-#define KEY_PAUSECD 201
-#define KEY_PROG3 202
-#define KEY_PROG4 203
-#define KEY_DASHBOARD 204 /* AL Dashboard */
-#define KEY_SUSPEND 205
-#define KEY_CLOSE 206 /* AC Close */
-#define KEY_PLAY 207
-#define KEY_FASTFORWARD 208
-#define KEY_BASSBOOST 209
-#define KEY_PRINT 210 /* AC Print */
-#define KEY_HP 211
-#define KEY_CAMERA 212
-#define KEY_SOUND 213
-#define KEY_QUESTION 214
-#define KEY_EMAIL 215
-#define KEY_CHAT 216
-#define KEY_SEARCH 217
-#define KEY_CONNECT 218
-#define KEY_FINANCE 219 /* AL Checkbook/Finance */
-#define KEY_SPORT 220
-#define KEY_SHOP 221
-#define KEY_ALTERASE 222
-#define KEY_CANCEL 223 /* AC Cancel */
-#define KEY_BRIGHTNESSDOWN 224
-#define KEY_BRIGHTNESSUP 225
-#define KEY_MEDIA 226
-
-#define KEY_SWITCHVIDEOMODE 227 /* Cycle between available video
- outputs (Monitor/LCD/TV-out/etc) */
-#define KEY_KBDILLUMTOGGLE 228
-#define KEY_KBDILLUMDOWN 229
-#define KEY_KBDILLUMUP 230
-
-#define KEY_SEND 231 /* AC Send */
-#define KEY_REPLY 232 /* AC Reply */
-#define KEY_FORWARDMAIL 233 /* AC Forward Msg */
-#define KEY_SAVE 234 /* AC Save */
-#define KEY_DOCUMENTS 235
-
-#define KEY_BATTERY 236
-
-#define KEY_BLUETOOTH 237
-#define KEY_WLAN 238
-#define KEY_UWB 239
-
-#define KEY_UNKNOWN 240
-
-#define KEY_VIDEO_NEXT 241 /* drive next video source */
-#define KEY_VIDEO_PREV 242 /* drive previous video source */
-#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */
-#define KEY_BRIGHTNESS_AUTO 244 /* Set Auto Brightness: manual
- brightness control is off,
- rely on ambient */
-#define KEY_BRIGHTNESS_ZERO KEY_BRIGHTNESS_AUTO
-#define KEY_DISPLAY_OFF 245 /* display device to off state */
-
-#define KEY_WWAN 246 /* Wireless WAN (LTE, UMTS, GSM, etc.) */
-#define KEY_WIMAX KEY_WWAN
-#define KEY_RFKILL 247 /* Key that controls all radios */
-
-#define KEY_MICMUTE 248 /* Mute / unmute the microphone */
-
-/* Code 255 is reserved for special needs of AT keyboard driver */
-
-#define BTN_MISC 0x100
-#define BTN_0 0x100
-#define BTN_1 0x101
-#define BTN_2 0x102
-#define BTN_3 0x103
-#define BTN_4 0x104
-#define BTN_5 0x105
-#define BTN_6 0x106
-#define BTN_7 0x107
-#define BTN_8 0x108
-#define BTN_9 0x109
-
-#define BTN_MOUSE 0x110
-#define BTN_LEFT 0x110
-#define BTN_RIGHT 0x111
-#define BTN_MIDDLE 0x112
-#define BTN_SIDE 0x113
-#define BTN_EXTRA 0x114
-#define BTN_FORWARD 0x115
-#define BTN_BACK 0x116
-#define BTN_TASK 0x117
-
-#define BTN_JOYSTICK 0x120
-#define BTN_TRIGGER 0x120
-#define BTN_THUMB 0x121
-#define BTN_THUMB2 0x122
-#define BTN_TOP 0x123
-#define BTN_TOP2 0x124
-#define BTN_PINKIE 0x125
-#define BTN_BASE 0x126
-#define BTN_BASE2 0x127
-#define BTN_BASE3 0x128
-#define BTN_BASE4 0x129
-#define BTN_BASE5 0x12a
-#define BTN_BASE6 0x12b
-#define BTN_DEAD 0x12f
-
-#define BTN_GAMEPAD 0x130
-#define BTN_SOUTH 0x130
-#define BTN_A BTN_SOUTH
-#define BTN_EAST 0x131
-#define BTN_B BTN_EAST
-#define BTN_C 0x132
-#define BTN_NORTH 0x133
-#define BTN_X BTN_NORTH
-#define BTN_WEST 0x134
-#define BTN_Y BTN_WEST
-#define BTN_Z 0x135
-#define BTN_TL 0x136
-#define BTN_TR 0x137
-#define BTN_TL2 0x138
-#define BTN_TR2 0x139
-#define BTN_SELECT 0x13a
-#define BTN_START 0x13b
-#define BTN_MODE 0x13c
-#define BTN_THUMBL 0x13d
-#define BTN_THUMBR 0x13e
-
-#define BTN_DIGI 0x140
-#define BTN_TOOL_PEN 0x140
-#define BTN_TOOL_RUBBER 0x141
-#define BTN_TOOL_BRUSH 0x142
-#define BTN_TOOL_PENCIL 0x143
-#define BTN_TOOL_AIRBRUSH 0x144
-#define BTN_TOOL_FINGER 0x145
-#define BTN_TOOL_MOUSE 0x146
-#define BTN_TOOL_LENS 0x147
-#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */
-#define BTN_TOUCH 0x14a
-#define BTN_STYLUS 0x14b
-#define BTN_STYLUS2 0x14c
-#define BTN_TOOL_DOUBLETAP 0x14d
-#define BTN_TOOL_TRIPLETAP 0x14e
-#define BTN_TOOL_QUADTAP 0x14f /* Four fingers on trackpad */
-
-#define BTN_WHEEL 0x150
-#define BTN_GEAR_DOWN 0x150
-#define BTN_GEAR_UP 0x151
-
-#define KEY_OK 0x160
-#define KEY_SELECT 0x161
-#define KEY_GOTO 0x162
-#define KEY_CLEAR 0x163
-#define KEY_POWER2 0x164
-#define KEY_OPTION 0x165
-#define KEY_INFO 0x166 /* AL OEM Features/Tips/Tutorial */
-#define KEY_TIME 0x167
-#define KEY_VENDOR 0x168
-#define KEY_ARCHIVE 0x169
-#define KEY_PROGRAM 0x16a /* Media Select Program Guide */
-#define KEY_CHANNEL 0x16b
-#define KEY_FAVORITES 0x16c
-#define KEY_EPG 0x16d
-#define KEY_PVR 0x16e /* Media Select Home */
-#define KEY_MHP 0x16f
-#define KEY_LANGUAGE 0x170
-#define KEY_TITLE 0x171
-#define KEY_SUBTITLE 0x172
-#define KEY_ANGLE 0x173
-#define KEY_ZOOM 0x174
-#define KEY_MODE 0x175
-#define KEY_KEYBOARD 0x176
-#define KEY_SCREEN 0x177
-#define KEY_PC 0x178 /* Media Select Computer */
-#define KEY_TV 0x179 /* Media Select TV */
-#define KEY_TV2 0x17a /* Media Select Cable */
-#define KEY_VCR 0x17b /* Media Select VCR */
-#define KEY_VCR2 0x17c /* VCR Plus */
-#define KEY_SAT 0x17d /* Media Select Satellite */
-#define KEY_SAT2 0x17e
-#define KEY_CD 0x17f /* Media Select CD */
-#define KEY_TAPE 0x180 /* Media Select Tape */
-#define KEY_RADIO 0x181
-#define KEY_TUNER 0x182 /* Media Select Tuner */
-#define KEY_PLAYER 0x183
-#define KEY_TEXT 0x184
-#define KEY_DVD 0x185 /* Media Select DVD */
-#define KEY_AUX 0x186
-#define KEY_MP3 0x187
-#define KEY_AUDIO 0x188 /* AL Audio Browser */
-#define KEY_VIDEO 0x189 /* AL Movie Browser */
-#define KEY_DIRECTORY 0x18a
-#define KEY_LIST 0x18b
-#define KEY_MEMO 0x18c /* Media Select Messages */
-#define KEY_CALENDAR 0x18d
-#define KEY_RED 0x18e
-#define KEY_GREEN 0x18f
-#define KEY_YELLOW 0x190
-#define KEY_BLUE 0x191
-#define KEY_CHANNELUP 0x192 /* Channel Increment */
-#define KEY_CHANNELDOWN 0x193 /* Channel Decrement */
-#define KEY_FIRST 0x194
-#define KEY_LAST 0x195 /* Recall Last */
-#define KEY_AB 0x196
-#define KEY_NEXT 0x197
-#define KEY_RESTART 0x198
-#define KEY_SLOW 0x199
-#define KEY_SHUFFLE 0x19a
-#define KEY_BREAK 0x19b
-#define KEY_PREVIOUS 0x19c
-#define KEY_DIGITS 0x19d
-#define KEY_TEEN 0x19e
-#define KEY_TWEN 0x19f
-#define KEY_VIDEOPHONE 0x1a0 /* Media Select Video Phone */
-#define KEY_GAMES 0x1a1 /* Media Select Games */
-#define KEY_ZOOMIN 0x1a2 /* AC Zoom In */
-#define KEY_ZOOMOUT 0x1a3 /* AC Zoom Out */
-#define KEY_ZOOMRESET 0x1a4 /* AC Zoom */
-#define KEY_WORDPROCESSOR 0x1a5 /* AL Word Processor */
-#define KEY_EDITOR 0x1a6 /* AL Text Editor */
-#define KEY_SPREADSHEET 0x1a7 /* AL Spreadsheet */
-#define KEY_GRAPHICSEDITOR 0x1a8 /* AL Graphics Editor */
-#define KEY_PRESENTATION 0x1a9 /* AL Presentation App */
-#define KEY_DATABASE 0x1aa /* AL Database App */
-#define KEY_NEWS 0x1ab /* AL Newsreader */
-#define KEY_VOICEMAIL 0x1ac /* AL Voicemail */
-#define KEY_ADDRESSBOOK 0x1ad /* AL Contacts/Address Book */
-#define KEY_MESSENGER 0x1ae /* AL Instant Messaging */
-#define KEY_DISPLAYTOGGLE 0x1af /* Turn display (LCD) on and off */
-#define KEY_BRIGHTNESS_TOGGLE KEY_DISPLAYTOGGLE
-#define KEY_SPELLCHECK 0x1b0 /* AL Spell Check */
-#define KEY_LOGOFF 0x1b1 /* AL Logoff */
-
-#define KEY_DOLLAR 0x1b2
-#define KEY_EURO 0x1b3
-
-#define KEY_FRAMEBACK 0x1b4 /* Consumer - transport controls */
-#define KEY_FRAMEFORWARD 0x1b5
-#define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */
-#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
-#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
-#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
-#define KEY_IMAGES 0x1ba /* AL Image Browser */
-
-#define KEY_DEL_EOL 0x1c0
-#define KEY_DEL_EOS 0x1c1
-#define KEY_INS_LINE 0x1c2
-#define KEY_DEL_LINE 0x1c3
-
-#define KEY_FN 0x1d0
-#define KEY_FN_ESC 0x1d1
-#define KEY_FN_F1 0x1d2
-#define KEY_FN_F2 0x1d3
-#define KEY_FN_F3 0x1d4
-#define KEY_FN_F4 0x1d5
-#define KEY_FN_F5 0x1d6
-#define KEY_FN_F6 0x1d7
-#define KEY_FN_F7 0x1d8
-#define KEY_FN_F8 0x1d9
-#define KEY_FN_F9 0x1da
-#define KEY_FN_F10 0x1db
-#define KEY_FN_F11 0x1dc
-#define KEY_FN_F12 0x1dd
-#define KEY_FN_1 0x1de
-#define KEY_FN_2 0x1df
-#define KEY_FN_D 0x1e0
-#define KEY_FN_E 0x1e1
-#define KEY_FN_F 0x1e2
-#define KEY_FN_S 0x1e3
-#define KEY_FN_B 0x1e4
-
-#define KEY_BRL_DOT1 0x1f1
-#define KEY_BRL_DOT2 0x1f2
-#define KEY_BRL_DOT3 0x1f3
-#define KEY_BRL_DOT4 0x1f4
-#define KEY_BRL_DOT5 0x1f5
-#define KEY_BRL_DOT6 0x1f6
-#define KEY_BRL_DOT7 0x1f7
-#define KEY_BRL_DOT8 0x1f8
-#define KEY_BRL_DOT9 0x1f9
-#define KEY_BRL_DOT10 0x1fa
-
-#define KEY_NUMERIC_0 0x200 /* used by phones, remote controls, */
-#define KEY_NUMERIC_1 0x201 /* and other keypads */
-#define KEY_NUMERIC_2 0x202
-#define KEY_NUMERIC_3 0x203
-#define KEY_NUMERIC_4 0x204
-#define KEY_NUMERIC_5 0x205
-#define KEY_NUMERIC_6 0x206
-#define KEY_NUMERIC_7 0x207
-#define KEY_NUMERIC_8 0x208
-#define KEY_NUMERIC_9 0x209
-#define KEY_NUMERIC_STAR 0x20a
-#define KEY_NUMERIC_POUND 0x20b
-#define KEY_NUMERIC_A 0x20c /* Phone key A - HUT Telephony 0xb9 */
-#define KEY_NUMERIC_B 0x20d
-#define KEY_NUMERIC_C 0x20e
-#define KEY_NUMERIC_D 0x20f
-
-#define KEY_CAMERA_FOCUS 0x210
-#define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */
-
-#define KEY_TOUCHPAD_TOGGLE 0x212 /* Request switch touchpad on or off */
-#define KEY_TOUCHPAD_ON 0x213
-#define KEY_TOUCHPAD_OFF 0x214
-
-#define KEY_CAMERA_ZOOMIN 0x215
-#define KEY_CAMERA_ZOOMOUT 0x216
-#define KEY_CAMERA_UP 0x217
-#define KEY_CAMERA_DOWN 0x218
-#define KEY_CAMERA_LEFT 0x219
-#define KEY_CAMERA_RIGHT 0x21a
-
-#define KEY_ATTENDANT_ON 0x21b
-#define KEY_ATTENDANT_OFF 0x21c
-#define KEY_ATTENDANT_TOGGLE 0x21d /* Attendant call on or off */
-#define KEY_LIGHTS_TOGGLE 0x21e /* Reading light on or off */
-
-#define BTN_DPAD_UP 0x220
-#define BTN_DPAD_DOWN 0x221
-#define BTN_DPAD_LEFT 0x222
-#define BTN_DPAD_RIGHT 0x223
-
-#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
-
-#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
-#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
-#define KEY_JOURNAL 0x242 /* AL Log/Journal/Timecard */
-#define KEY_CONTROLPANEL 0x243 /* AL Control Panel */
-#define KEY_APPSELECT 0x244 /* AL Select Task/Application */
-#define KEY_SCREENSAVER 0x245 /* AL Screen Saver */
-#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
-
-#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
-#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
-
-#define KEY_KBDINPUTASSIST_PREV 0x260
-#define KEY_KBDINPUTASSIST_NEXT 0x261
-#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
-#define KEY_KBDINPUTASSIST_NEXTGROUP 0x263
-#define KEY_KBDINPUTASSIST_ACCEPT 0x264
-#define KEY_KBDINPUTASSIST_CANCEL 0x265
-
-#define BTN_TRIGGER_HAPPY 0x2c0
-#define BTN_TRIGGER_HAPPY1 0x2c0
-#define BTN_TRIGGER_HAPPY2 0x2c1
-#define BTN_TRIGGER_HAPPY3 0x2c2
-#define BTN_TRIGGER_HAPPY4 0x2c3
-#define BTN_TRIGGER_HAPPY5 0x2c4
-#define BTN_TRIGGER_HAPPY6 0x2c5
-#define BTN_TRIGGER_HAPPY7 0x2c6
-#define BTN_TRIGGER_HAPPY8 0x2c7
-#define BTN_TRIGGER_HAPPY9 0x2c8
-#define BTN_TRIGGER_HAPPY10 0x2c9
-#define BTN_TRIGGER_HAPPY11 0x2ca
-#define BTN_TRIGGER_HAPPY12 0x2cb
-#define BTN_TRIGGER_HAPPY13 0x2cc
-#define BTN_TRIGGER_HAPPY14 0x2cd
-#define BTN_TRIGGER_HAPPY15 0x2ce
-#define BTN_TRIGGER_HAPPY16 0x2cf
-#define BTN_TRIGGER_HAPPY17 0x2d0
-#define BTN_TRIGGER_HAPPY18 0x2d1
-#define BTN_TRIGGER_HAPPY19 0x2d2
-#define BTN_TRIGGER_HAPPY20 0x2d3
-#define BTN_TRIGGER_HAPPY21 0x2d4
-#define BTN_TRIGGER_HAPPY22 0x2d5
-#define BTN_TRIGGER_HAPPY23 0x2d6
-#define BTN_TRIGGER_HAPPY24 0x2d7
-#define BTN_TRIGGER_HAPPY25 0x2d8
-#define BTN_TRIGGER_HAPPY26 0x2d9
-#define BTN_TRIGGER_HAPPY27 0x2da
-#define BTN_TRIGGER_HAPPY28 0x2db
-#define BTN_TRIGGER_HAPPY29 0x2dc
-#define BTN_TRIGGER_HAPPY30 0x2dd
-#define BTN_TRIGGER_HAPPY31 0x2de
-#define BTN_TRIGGER_HAPPY32 0x2df
-#define BTN_TRIGGER_HAPPY33 0x2e0
-#define BTN_TRIGGER_HAPPY34 0x2e1
-#define BTN_TRIGGER_HAPPY35 0x2e2
-#define BTN_TRIGGER_HAPPY36 0x2e3
-#define BTN_TRIGGER_HAPPY37 0x2e4
-#define BTN_TRIGGER_HAPPY38 0x2e5
-#define BTN_TRIGGER_HAPPY39 0x2e6
-#define BTN_TRIGGER_HAPPY40 0x2e7
-
-/* We avoid low common keys in module aliases so they don't get huge. */
-#define KEY_MIN_INTERESTING KEY_MUTE
-#define KEY_MAX 0x2ff
-#define KEY_CNT (KEY_MAX+1)
-
-/*
- * Relative axes
- */
-
-#define REL_X 0x00
-#define REL_Y 0x01
-#define REL_Z 0x02
-#define REL_RX 0x03
-#define REL_RY 0x04
-#define REL_RZ 0x05
-#define REL_HWHEEL 0x06
-#define REL_DIAL 0x07
-#define REL_WHEEL 0x08
-#define REL_MISC 0x09
-#define REL_MAX 0x0f
-#define REL_CNT (REL_MAX+1)
-
-/*
- * Absolute axes
- */
-
-#define ABS_X 0x00
-#define ABS_Y 0x01
-#define ABS_Z 0x02
-#define ABS_RX 0x03
-#define ABS_RY 0x04
-#define ABS_RZ 0x05
-#define ABS_THROTTLE 0x06
-#define ABS_RUDDER 0x07
-#define ABS_WHEEL 0x08
-#define ABS_GAS 0x09
-#define ABS_BRAKE 0x0a
-#define ABS_HAT0X 0x10
-#define ABS_HAT0Y 0x11
-#define ABS_HAT1X 0x12
-#define ABS_HAT1Y 0x13
-#define ABS_HAT2X 0x14
-#define ABS_HAT2Y 0x15
-#define ABS_HAT3X 0x16
-#define ABS_HAT3Y 0x17
-#define ABS_PRESSURE 0x18
-#define ABS_DISTANCE 0x19
-#define ABS_TILT_X 0x1a
-#define ABS_TILT_Y 0x1b
-#define ABS_TOOL_WIDTH 0x1c
-
-#define ABS_VOLUME 0x20
-
-#define ABS_MISC 0x28
-
-#define ABS_MT_SLOT 0x2f /* MT slot being modified */
-#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
-#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
-#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
-#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
-#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
-#define ABS_MT_POSITION_X 0x35 /* Center X touch position */
-#define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */
-#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
-#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
-#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
-#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
-#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */
-#define ABS_MT_TOOL_X 0x3c /* Center X tool position */
-#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
-
-
-#define ABS_MAX 0x3f
-#define ABS_CNT (ABS_MAX+1)
-
-/*
- * Switch events
- */
-
-#define SW_LID 0x00 /* set = lid shut */
-#define SW_TABLET_MODE 0x01 /* set = tablet mode */
-#define SW_HEADPHONE_INSERT 0x02 /* set = inserted */
-#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any"
- set = radio enabled */
-#define SW_RADIO SW_RFKILL_ALL /* deprecated */
-#define SW_MICROPHONE_INSERT 0x04 /* set = inserted */
-#define SW_DOCK 0x05 /* set = plugged into dock */
-#define SW_LINEOUT_INSERT 0x06 /* set = inserted */
-#define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */
-#define SW_VIDEOOUT_INSERT 0x08 /* set = inserted */
-#define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */
-#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */
-#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
-#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
-#define SW_LINEIN_INSERT 0x0d /* set = inserted */
-#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
-#define SW_MAX_ 0x0f
-#define SW_CNT (SW_MAX_+1)
-
-/*
- * Misc events
- */
-
-#define MSC_SERIAL 0x00
-#define MSC_PULSELED 0x01
-#define MSC_GESTURE 0x02
-#define MSC_RAW 0x03
-#define MSC_SCAN 0x04
-#define MSC_TIMESTAMP 0x05
-#define MSC_MAX 0x07
-#define MSC_CNT (MSC_MAX+1)
-
-/*
- * LEDs
- */
-
-#define LED_NUML 0x00
-#define LED_CAPSL 0x01
-#define LED_SCROLLL 0x02
-#define LED_COMPOSE 0x03
-#define LED_KANA 0x04
-#define LED_SLEEP 0x05
-#define LED_SUSPEND 0x06
-#define LED_MUTE 0x07
-#define LED_MISC 0x08
-#define LED_MAIL 0x09
-#define LED_CHARGING 0x0a
-#define LED_MAX 0x0f
-#define LED_CNT (LED_MAX+1)
-
-/*
- * Autorepeat values
+ * This ioctl allows user to retrieve the current event mask for specific
+ * event type. The argument must be of type "struct input_mask" and
+ * specifies the event type to query, the address of the receive buffer and
+ * the size of the receive buffer.
+ *
+ * The event mask is a per-client mask that specifies which events are
+ * forwarded to the client. Each event code is represented by a single bit
+ * in the event mask. If the bit is set, the event is passed to the client
+ * normally. Otherwise, the event is filtered and will never be queued on
+ * the client's receive buffer.
+ *
+ * Event masks do not affect global state of the input device. They only
+ * affect the file descriptor they are applied to.
+ *
+ * The default event mask for a client has all bits set, i.e. all events
+ * are forwarded to the client. If the kernel is queried for an unknown
+ * event type or if the receive buffer is larger than the number of
+ * event codes known to the kernel, the kernel returns all zeroes for those
+ * codes.
+ *
+ * At maximum, codes_size bytes are copied.
+ *
+ * This ioctl may fail with ENODEV in case the file is revoked, EFAULT
+ * if the receive-buffer points to invalid memory, or EINVAL if the kernel
+ * does not implement the ioctl.
*/
+#define EVIOCGMASK _IOR('E', 0x92, struct input_mask) /* Get event-masks */
-#define REP_DELAY 0x00
-#define REP_PERIOD 0x01
-#define REP_MAX 0x01
-#define REP_CNT (REP_MAX+1)
-
-/*
- * Sounds
+/**
+ * EVIOCSMASK - Set event mask
+ *
+ * This ioctl is the counterpart to EVIOCGMASK. Instead of receiving the
+ * current event mask, this changes the client's event mask for a specific
+ * type. See EVIOCGMASK for a description of event-masks and the
+ * argument-type.
+ *
+ * This ioctl provides full forward compatibility. If the passed event type
+ * is unknown to the kernel, or if the number of event codes specified in
+ * the mask is bigger than what is known to the kernel, the ioctl is still
+ * accepted and applied. However, any unknown codes are left untouched and
+ * stay cleared. That means, the kernel always filters unknown codes
+ * regardless of what the client requests. If the new mask doesn't cover
+ * all known event-codes, all remaining codes are automatically cleared and
+ * thus filtered.
+ *
+ * This ioctl may fail with ENODEV in case the file is revoked. EFAULT is
+ * returned if the receive-buffer points to invalid memory. EINVAL is returned
+ * if the kernel does not implement the ioctl.
*/
+#define EVIOCSMASK _IOW('E', 0x93, struct input_mask) /* Set event-masks */
-#define SND_CLICK 0x00
-#define SND_BELL 0x01
-#define SND_TONE 0x02
-#define SND_MAX 0x07
-#define SND_CNT (SND_MAX+1)
+#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
/*
* IDs.
@@ -1197,6 +471,14 @@ struct ff_effect {
#define FF_GAIN 0x60
#define FF_AUTOCENTER 0x61
+/*
+ * ff->playback(effect_id = FF_GAIN) is the first effect_id to
+ * cause a collision with another ff method, in this case ff->set_gain().
+ * Therefore the greatest safe value for effect_id is FF_GAIN - 1,
+ * and thus the total number of effects should never exceed FF_GAIN.
+ */
+#define FF_MAX_EFFECTS FF_GAIN
+
#define FF_MAX 0x7f
#define FF_CNT (FF_MAX+1)
diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h
index 413417f370..1becea86c7 100644
--- a/include/standard-headers/linux/pci_regs.h
+++ b/include/standard-headers/linux/pci_regs.h
@@ -216,7 +216,8 @@
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
#define PCI_CAP_ID_SATA 0x12 /* SATA Data/Index Conf. */
#define PCI_CAP_ID_AF 0x13 /* PCI Advanced Features */
-#define PCI_CAP_ID_MAX PCI_CAP_ID_AF
+#define PCI_CAP_ID_EA 0x14 /* PCI Enhanced Allocation */
+#define PCI_CAP_ID_MAX PCI_CAP_ID_EA
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
#define PCI_CAP_SIZEOF 4
@@ -353,6 +354,46 @@
#define PCI_AF_STATUS_TP 0x01
#define PCI_CAP_AF_SIZEOF 6 /* size of AF registers */
+/* PCI Enhanced Allocation registers */
+
+#define PCI_EA_NUM_ENT 2 /* Number of Capability Entries */
+#define PCI_EA_NUM_ENT_MASK 0x3f /* Num Entries Mask */
+#define PCI_EA_FIRST_ENT 4 /* First EA Entry in List */
+#define PCI_EA_FIRST_ENT_BRIDGE 8 /* First EA Entry for Bridges */
+#define PCI_EA_ES 0x00000007 /* Entry Size */
+#define PCI_EA_BEI 0x000000f0 /* BAR Equivalent Indicator */
+/* 0-5 map to BARs 0-5 respectively */
+#define PCI_EA_BEI_BAR0 0
+#define PCI_EA_BEI_BAR5 5
+#define PCI_EA_BEI_BRIDGE 6 /* Resource behind bridge */
+#define PCI_EA_BEI_ENI 7 /* Equivalent Not Indicated */
+#define PCI_EA_BEI_ROM 8 /* Expansion ROM */
+/* 9-14 map to VF BARs 0-5 respectively */
+#define PCI_EA_BEI_VF_BAR0 9
+#define PCI_EA_BEI_VF_BAR5 14
+#define PCI_EA_BEI_RESERVED 15 /* Reserved - Treat like ENI */
+#define PCI_EA_PP 0x0000ff00 /* Primary Properties */
+#define PCI_EA_SP 0x00ff0000 /* Secondary Properties */
+#define PCI_EA_P_MEM 0x00 /* Non-Prefetch Memory */
+#define PCI_EA_P_MEM_PREFETCH 0x01 /* Prefetchable Memory */
+#define PCI_EA_P_IO 0x02 /* I/O Space */
+#define PCI_EA_P_VF_MEM_PREFETCH 0x03 /* VF Prefetchable Memory */
+#define PCI_EA_P_VF_MEM 0x04 /* VF Non-Prefetch Memory */
+#define PCI_EA_P_BRIDGE_MEM 0x05 /* Bridge Non-Prefetch Memory */
+#define PCI_EA_P_BRIDGE_MEM_PREFETCH 0x06 /* Bridge Prefetchable Memory */
+#define PCI_EA_P_BRIDGE_IO 0x07 /* Bridge I/O Space */
+/* 0x08-0xfc reserved */
+#define PCI_EA_P_MEM_RESERVED 0xfd /* Reserved Memory */
+#define PCI_EA_P_IO_RESERVED 0xfe /* Reserved I/O Space */
+#define PCI_EA_P_UNAVAILABLE 0xff /* Entry Unavailable */
+#define PCI_EA_WRITABLE 0x40000000 /* Writable: 1 = RW, 0 = HwInit */
+#define PCI_EA_ENABLE 0x80000000 /* Enable for this entry */
+#define PCI_EA_BASE 4 /* Base Address Offset */
+#define PCI_EA_MAX_OFFSET 8 /* MaxOffset (resource length) */
+/* bit 0 is reserved */
+#define PCI_EA_IS_64 0x00000002 /* 64-bit field flag */
+#define PCI_EA_FIELD_MASK 0xfffffffc /* For Base & Max Offset */
+
/* PCI-X registers (Type 0 (non-bridge) devices) */
#define PCI_X_CMD 2 /* Modes & Features */
diff --git a/include/standard-headers/linux/virtio_gpu.h b/include/standard-headers/linux/virtio_gpu.h
index 76e5e52929..c1c8f0751d 100644
--- a/include/standard-headers/linux/virtio_gpu.h
+++ b/include/standard-headers/linux/virtio_gpu.h
@@ -40,7 +40,7 @@
#include "standard-headers/linux/types.h"
-#define VIRTIO_GPU_FEATURE_VIRGL 0
+#define VIRTIO_GPU_F_VIRGL 0
enum virtio_gpu_ctrl_type {
VIRTIO_GPU_UNDEFINED = 0,
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index b31f325fa2..7741f91f9c 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -43,6 +43,7 @@
extern bool kvm_allowed;
extern bool kvm_kernel_irqchip;
+extern bool kvm_split_irqchip;
extern bool kvm_async_interrupts_allowed;
extern bool kvm_halt_in_kernel_allowed;
extern bool kvm_eventfds_allowed;
@@ -71,6 +72,16 @@ extern bool kvm_ioeventfd_any_length_allowed;
#define kvm_irqchip_in_kernel() (kvm_kernel_irqchip)
/**
+ * kvm_irqchip_is_split:
+ *
+ * Returns: true if the user asked us to split the irqchip
+ * implementation between user and kernel space. The details are
+ * architecture and machine specific. On PC, it means that the PIC,
+ * IOAPIC, and PIT are in user space while the LAPIC is in the kernel.
+ */
+#define kvm_irqchip_is_split() (kvm_split_irqchip)
+
+/**
* kvm_async_interrupts_enabled:
*
* Returns: true if we can deliver interrupts to KVM
@@ -163,6 +174,7 @@ extern bool kvm_ioeventfd_any_length_allowed;
#else
#define kvm_enabled() (0)
#define kvm_irqchip_in_kernel() (false)
+#define kvm_irqchip_is_split() (false)
#define kvm_async_interrupts_enabled() (false)
#define kvm_halt_in_kernel() (false)
#define kvm_eventfds_enabled() (false)
@@ -306,6 +318,8 @@ MemTxAttrs kvm_arch_post_run(CPUState *cpu, struct kvm_run *run);
int kvm_arch_handle_exit(CPUState *cpu, struct kvm_run *run);
+int kvm_arch_handle_ioapic_eoi(CPUState *cpu, struct kvm_run *run);
+
int kvm_arch_process_async_events(CPUState *cpu);
int kvm_arch_get_registers(CPUState *cpu);
@@ -455,6 +469,7 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
void kvm_irqchip_release_virq(KVMState *s, int virq);
int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter);
+int kvm_irqchip_add_hv_sint_route(KVMState *s, uint32_t vcpu, uint32_t sint);
int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
EventNotifier *rn, int virq);
@@ -472,6 +487,7 @@ void kvm_init_irq_routing(KVMState *s);
/**
* kvm_arch_irqchip_create:
* @KVMState: The KVMState pointer
+ * @MachineState: The MachineState pointer
*
* Allow architectures to create an in-kernel irq chip themselves.
*
@@ -479,7 +495,7 @@ void kvm_init_irq_routing(KVMState *s);
* 0: irq chip was not created
* > 0: irq chip was created
*/
-int kvm_arch_irqchip_create(KVMState *s);
+int kvm_arch_irqchip_create(MachineState *ms, KVMState *s);
/**
* kvm_set_one_reg - set a register value in KVM via KVM_SET_ONE_REG ioctl
diff --git a/kvm-all.c b/kvm-all.c
index c648b814ec..bd9e7641b2 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -45,8 +45,10 @@
#include <sys/eventfd.h>
#endif
-/* KVM uses PAGE_SIZE in its definition of COALESCED_MMIO_MAX */
-#define PAGE_SIZE TARGET_PAGE_SIZE
+/* KVM uses PAGE_SIZE in its definition of KVM_COALESCED_MMIO_MAX. We
+ * need to use the real host PAGE_SIZE, as that's what KVM will use.
+ */
+#define PAGE_SIZE getpagesize()
//#define DEBUG_KVM
@@ -97,6 +99,7 @@ struct KVMState
KVMState *kvm_state;
bool kvm_kernel_irqchip;
+bool kvm_split_irqchip;
bool kvm_async_interrupts_allowed;
bool kvm_halt_in_kernel_allowed;
bool kvm_eventfds_allowed;
@@ -1298,6 +1301,34 @@ int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter)
return virq;
}
+int kvm_irqchip_add_hv_sint_route(KVMState *s, uint32_t vcpu, uint32_t sint)
+{
+ struct kvm_irq_routing_entry kroute = {};
+ int virq;
+
+ if (!kvm_gsi_routing_enabled()) {
+ return -ENOSYS;
+ }
+ if (!kvm_check_extension(s, KVM_CAP_HYPERV_SYNIC)) {
+ return -ENOSYS;
+ }
+ virq = kvm_irqchip_get_virq(s);
+ if (virq < 0) {
+ return virq;
+ }
+
+ kroute.gsi = virq;
+ kroute.type = KVM_IRQ_ROUTING_HV_SINT;
+ kroute.flags = 0;
+ kroute.u.hv_sint.vcpu = vcpu;
+ kroute.u.hv_sint.sint = sint;
+
+ kvm_add_routing_entry(s, &kroute);
+ kvm_irqchip_commit_routes(s);
+
+ return virq;
+}
+
#else /* !KVM_CAP_IRQ_ROUTING */
void kvm_init_irq_routing(KVMState *s)
@@ -1323,6 +1354,11 @@ int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter)
return -ENOSYS;
}
+int kvm_irqchip_add_hv_sint_route(KVMState *s, uint32_t vcpu, uint32_t sint)
+{
+ return -ENOSYS;
+}
+
static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
{
abort();
@@ -1395,9 +1431,14 @@ static void kvm_irqchip_create(MachineState *machine, KVMState *s)
/* First probe and see if there's a arch-specific hook to create the
* in-kernel irqchip for us */
- ret = kvm_arch_irqchip_create(s);
+ ret = kvm_arch_irqchip_create(machine, s);
if (ret == 0) {
- ret = kvm_vm_ioctl(s, KVM_CREATE_IRQCHIP);
+ if (machine_kernel_irqchip_split(machine)) {
+ perror("Split IRQ chip mode not supported.");
+ exit(1);
+ } else {
+ ret = kvm_vm_ioctl(s, KVM_CREATE_IRQCHIP);
+ }
}
if (ret < 0) {
fprintf(stderr, "Create kernel irqchip failed: %s\n", strerror(-ret));
@@ -1626,8 +1667,10 @@ static int kvm_init(MachineState *ms)
kvm_state = s;
- s->memory_listener.listener.eventfd_add = kvm_mem_ioeventfd_add;
- s->memory_listener.listener.eventfd_del = kvm_mem_ioeventfd_del;
+ if (kvm_eventfds_allowed) {
+ s->memory_listener.listener.eventfd_add = kvm_mem_ioeventfd_add;
+ s->memory_listener.listener.eventfd_del = kvm_mem_ioeventfd_del;
+ }
s->memory_listener.listener.coalesced_mmio_add = kvm_coalesce_mmio_region;
s->memory_listener.listener.coalesced_mmio_del = kvm_uncoalesce_mmio_region;
diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
index d3714c0aaf..a2fd4d95b3 100644
--- a/linux-headers/asm-arm64/kvm.h
+++ b/linux-headers/asm-arm64/kvm.h
@@ -32,7 +32,7 @@
#ifndef __ASSEMBLY__
#include <linux/psci.h>
-#include <asm/types.h>
+#include <linux/types.h>
#include <asm/ptrace.h>
#define __KVM_HAVE_GUEST_DEBUG
diff --git a/linux-headers/asm-powerpc/unistd.h b/linux-headers/asm-powerpc/unistd.h
index 28deee06cb..1bf7e36747 100644
--- a/linux-headers/asm-powerpc/unistd.h
+++ b/linux-headers/asm-powerpc/unistd.h
@@ -388,5 +388,18 @@
#define __NR_switch_endian 363
#define __NR_userfaultfd 364
#define __NR_membarrier 365
+#define __NR_semop 366
+#define __NR_semget 367
+#define __NR_semctl 368
+#define __NR_semtimedop 369
+#define __NR_msgsnd 370
+#define __NR_msgrcv 371
+#define __NR_msgget 372
+#define __NR_msgctl 373
+#define __NR_shmat 374
+#define __NR_shmdt 375
+#define __NR_shmget 376
+#define __NR_shmctl 377
+#define __NR_mlock2 378
#endif /* _ASM_POWERPC_UNISTD_H_ */
diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index 512d8f1d4f..ac213a153a 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -66,6 +66,8 @@ struct kvm_s390_io_adapter_req {
#define KVM_S390_VM_MEM_CLR_CMMA 1
#define KVM_S390_VM_MEM_LIMIT_SIZE 2
+#define KVM_S390_NO_MEM_LIMIT U64_MAX
+
/* kvm attributes for KVM_S390_VM_TOD */
#define KVM_S390_VM_TOD_LOW 0
#define KVM_S390_VM_TOD_HIGH 1
diff --git a/linux-headers/asm-s390/unistd.h b/linux-headers/asm-s390/unistd.h
index 04b43b129a..bccd002258 100644
--- a/linux-headers/asm-s390/unistd.h
+++ b/linux-headers/asm-s390/unistd.h
@@ -192,14 +192,14 @@
#define __NR_set_tid_address 252
#define __NR_fadvise64 253
#define __NR_timer_create 254
-#define __NR_timer_settime (__NR_timer_create+1)
-#define __NR_timer_gettime (__NR_timer_create+2)
-#define __NR_timer_getoverrun (__NR_timer_create+3)
-#define __NR_timer_delete (__NR_timer_create+4)
-#define __NR_clock_settime (__NR_timer_create+5)
-#define __NR_clock_gettime (__NR_timer_create+6)
-#define __NR_clock_getres (__NR_timer_create+7)
-#define __NR_clock_nanosleep (__NR_timer_create+8)
+#define __NR_timer_settime 255
+#define __NR_timer_gettime 256
+#define __NR_timer_getoverrun 257
+#define __NR_timer_delete 258
+#define __NR_clock_settime 259
+#define __NR_clock_gettime 260
+#define __NR_clock_getres 261
+#define __NR_clock_nanosleep 262
/* Number 263 is reserved for vserver */
#define __NR_statfs64 265
#define __NR_fstatfs64 266
@@ -309,7 +309,8 @@
#define __NR_recvfrom 371
#define __NR_recvmsg 372
#define __NR_shutdown 373
-#define NR_syscalls 374
+#define __NR_mlock2 374
+#define NR_syscalls 375
/*
* There are some system calls that are not present on 64 bit, some
diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h
index 7570c80c49..30ff8fc56b 100644
--- a/linux-headers/asm-x86/unistd_32.h
+++ b/linux-headers/asm-x86/unistd_32.h
@@ -373,5 +373,6 @@
#define __NR_shutdown 373
#define __NR_userfaultfd 374
#define __NR_membarrier 375
+#define __NR_mlock2 376
#endif /* _ASM_X86_UNISTD_32_H */
diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h
index fdc7afb057..c8f7959390 100644
--- a/linux-headers/asm-x86/unistd_64.h
+++ b/linux-headers/asm-x86/unistd_64.h
@@ -326,5 +326,6 @@
#define __NR_execveat 322
#define __NR_userfaultfd 323
#define __NR_membarrier 324
+#define __NR_mlock2 325
#endif /* _ASM_X86_UNISTD_64_H */
diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h
index ac6d1980b5..27003f3049 100644
--- a/linux-headers/asm-x86/unistd_x32.h
+++ b/linux-headers/asm-x86/unistd_x32.h
@@ -281,6 +281,7 @@
#define __NR_bpf (__X32_SYSCALL_BIT + 321)
#define __NR_userfaultfd (__X32_SYSCALL_BIT + 323)
#define __NR_membarrier (__X32_SYSCALL_BIT + 324)
+#define __NR_mlock2 (__X32_SYSCALL_BIT + 325)
#define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
#define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
#define __NR_ioctl (__X32_SYSCALL_BIT + 514)
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index dcc410efe7..4e20262597 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -154,6 +154,20 @@ struct kvm_s390_skeys {
__u32 flags;
__u32 reserved[9];
};
+
+struct kvm_hyperv_exit {
+#define KVM_EXIT_HYPERV_SYNIC 1
+ __u32 type;
+ union {
+ struct {
+ __u32 msr;
+ __u64 control;
+ __u64 evt_page;
+ __u64 msg_page;
+ } synic;
+ } u;
+};
+
#define KVM_S390_GET_SKEYS_NONE 1
#define KVM_S390_SKEYS_MAX 1048576
@@ -184,6 +198,7 @@ struct kvm_s390_skeys {
#define KVM_EXIT_SYSTEM_EVENT 24
#define KVM_EXIT_S390_STSI 25
#define KVM_EXIT_IOAPIC_EOI 26
+#define KVM_EXIT_HYPERV 27
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -338,6 +353,8 @@ struct kvm_run {
struct {
__u8 vector;
} eoi;
+ /* KVM_EXIT_HYPERV */
+ struct kvm_hyperv_exit hyperv;
/* Fix the size of the union. */
char padding[256];
};
@@ -831,6 +848,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_GUEST_DEBUG_HW_WPS 120
#define KVM_CAP_SPLIT_IRQCHIP 121
#define KVM_CAP_IOEVENTFD_ANY_LENGTH 122
+#define KVM_CAP_HYPERV_SYNIC 123
#ifdef KVM_CAP_IRQ_ROUTING
@@ -854,10 +872,16 @@ struct kvm_irq_routing_s390_adapter {
__u32 adapter_id;
};
+struct kvm_irq_routing_hv_sint {
+ __u32 vcpu;
+ __u32 sint;
+};
+
/* gsi routing entry types */
#define KVM_IRQ_ROUTING_IRQCHIP 1
#define KVM_IRQ_ROUTING_MSI 2
#define KVM_IRQ_ROUTING_S390_ADAPTER 3
+#define KVM_IRQ_ROUTING_HV_SINT 4
struct kvm_irq_routing_entry {
__u32 gsi;
@@ -868,6 +892,7 @@ struct kvm_irq_routing_entry {
struct kvm_irq_routing_irqchip irqchip;
struct kvm_irq_routing_msi msi;
struct kvm_irq_routing_s390_adapter adapter;
+ struct kvm_irq_routing_hv_sint hv_sint;
__u32 pad[8];
} u;
};
diff --git a/linux-headers/linux/psci.h b/linux-headers/linux/psci.h
index 5a7676307b..08d443f7cf 100644
--- a/linux-headers/linux/psci.h
+++ b/linux-headers/linux/psci.h
@@ -46,6 +46,11 @@
#define PSCI_0_2_FN64_MIGRATE PSCI_0_2_FN64(5)
#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7)
+#define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10)
+#define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14)
+
+#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14)
+
/* PSCI v0.2 power state encoding for CPU_SUSPEND function */
#define PSCI_0_2_POWER_STATE_ID_MASK 0xffff
#define PSCI_0_2_POWER_STATE_ID_SHIFT 0
@@ -56,6 +61,13 @@
#define PSCI_0_2_POWER_STATE_AFFL_MASK \
(0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT)
+/* PSCI extended power state encoding for CPU_SUSPEND function */
+#define PSCI_1_0_EXT_POWER_STATE_ID_MASK 0xfffffff
+#define PSCI_1_0_EXT_POWER_STATE_ID_SHIFT 0
+#define PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT 30
+#define PSCI_1_0_EXT_POWER_STATE_TYPE_MASK \
+ (0x1 << PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT)
+
/* PSCI v0.2 affinity level state returned by AFFINITY_INFO */
#define PSCI_0_2_AFFINITY_LEVEL_ON 0
#define PSCI_0_2_AFFINITY_LEVEL_OFF 1
@@ -76,6 +88,11 @@
#define PSCI_VERSION_MINOR(ver) \
((ver) & PSCI_VERSION_MINOR_MASK)
+/* PSCI features decoding (>=1.0) */
+#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1
+#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK \
+ (0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT)
+
/* PSCI return values (inclusive of all PSCI versions) */
#define PSCI_RET_SUCCESS 0
#define PSCI_RET_NOT_SUPPORTED -1
@@ -86,5 +103,6 @@
#define PSCI_RET_INTERNAL_FAILURE -6
#define PSCI_RET_NOT_PRESENT -7
#define PSCI_RET_DISABLED -8
+#define PSCI_RET_INVALID_ADDRESS -9
#endif /* _LINUX_PSCI_H */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 8b17c0e94b..b90be1288b 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1743,7 +1743,7 @@ unsigned long init_guest_space(unsigned long host_start,
}
}
- qemu_log("Reserved 0x%lx bytes of guest address space\n", host_size);
+ qemu_log_mask(CPU_LOG_PAGE, "Reserved 0x%lx bytes of guest address space\n", host_size);
return real_start;
}
@@ -1784,9 +1784,9 @@ static void probe_guest_base(const char *image_name,
}
guest_base = real_start - loaddr;
- qemu_log("Relocating guest address space from 0x"
- TARGET_ABI_FMT_lx " to 0x%lx\n",
- loaddr, real_start);
+ qemu_log_mask(CPU_LOG_PAGE, "Relocating guest address space from 0x"
+ TARGET_ABI_FMT_lx " to 0x%lx\n",
+ loaddr, real_start);
}
return;
diff --git a/linux-user/main.c b/linux-user/main.c
index 8acfe0fdf4..ee1203584b 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -45,6 +45,18 @@ static const char *cpu_model;
unsigned long mmap_min_addr;
unsigned long guest_base;
int have_guest_base;
+
+#define EXCP_DUMP(env, fmt, ...) \
+do { \
+ CPUState *cs = ENV_GET_CPU(env); \
+ fprintf(stderr, fmt , ## __VA_ARGS__); \
+ cpu_dump_state(cs, stderr, fprintf, 0); \
+ if (qemu_log_separate()) { \
+ qemu_log(fmt, ## __VA_ARGS__); \
+ log_cpu_state(cs, 0); \
+ } \
+} while (0)
+
#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
/*
* When running 32-on-64 we should make sure we can fit all of the possible
@@ -416,8 +428,8 @@ void cpu_loop(CPUX86State *env)
break;
default:
pc = env->segs[R_CS].base + env->eip;
- fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
- (long)pc, trapnr);
+ EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
+ (long)pc, trapnr);
abort();
}
process_pending_signals(env);
@@ -865,9 +877,7 @@ void cpu_loop(CPUARMState *env)
break;
default:
error:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
- trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
process_pending_signals(env);
@@ -1056,9 +1066,7 @@ void cpu_loop(CPUARMState *env)
env->xregs[0] = do_arm_semihosting(env);
break;
default:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
- trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
process_pending_signals(env);
@@ -1148,8 +1156,7 @@ void cpu_loop(CPUUniCore32State *env)
}
error:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
#endif
@@ -1467,17 +1474,6 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
return -1;
}
-#define EXCP_DUMP(env, fmt, ...) \
-do { \
- CPUState *cs = ENV_GET_CPU(env); \
- fprintf(stderr, fmt , ## __VA_ARGS__); \
- cpu_dump_state(cs, stderr, fprintf, 0); \
- qemu_log(fmt, ## __VA_ARGS__); \
- if (qemu_log_enabled()) { \
- log_cpu_state(cs, 0); \
- } \
-} while (0)
-
static int do_store_exclusive(CPUPPCState *env)
{
target_ulong addr;
@@ -2636,9 +2632,7 @@ done_syscall:
break;
default:
error:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
- trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
process_pending_signals(env);
@@ -2661,11 +2655,11 @@ void cpu_loop(CPUOpenRISCState *env)
switch (trapnr) {
case EXCP_RESET:
- qemu_log("\nReset request, exit, pc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nReset request, exit, pc is %#x\n", env->pc);
exit(EXIT_FAILURE);
break;
case EXCP_BUSERR:
- qemu_log("\nBus error, exit, pc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nBus error, exit, pc is %#x\n", env->pc);
gdbsig = TARGET_SIGBUS;
break;
case EXCP_DPF:
@@ -2674,25 +2668,25 @@ void cpu_loop(CPUOpenRISCState *env)
gdbsig = TARGET_SIGSEGV;
break;
case EXCP_TICK:
- qemu_log("\nTick time interrupt pc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nTick time interrupt pc is %#x\n", env->pc);
break;
case EXCP_ALIGN:
- qemu_log("\nAlignment pc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nAlignment pc is %#x\n", env->pc);
gdbsig = TARGET_SIGBUS;
break;
case EXCP_ILLEGAL:
- qemu_log("\nIllegal instructionpc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nIllegal instructionpc is %#x\n", env->pc);
gdbsig = TARGET_SIGILL;
break;
case EXCP_INT:
- qemu_log("\nExternal interruptpc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nExternal interruptpc is %#x\n", env->pc);
break;
case EXCP_DTLBMISS:
case EXCP_ITLBMISS:
- qemu_log("\nTLB miss\n");
+ qemu_log_mask(CPU_LOG_INT, "\nTLB miss\n");
break;
case EXCP_RANGE:
- qemu_log("\nRange\n");
+ qemu_log_mask(CPU_LOG_INT, "\nRange\n");
gdbsig = TARGET_SIGSEGV;
break;
case EXCP_SYSCALL:
@@ -2707,19 +2701,18 @@ void cpu_loop(CPUOpenRISCState *env)
env->gpr[8], 0, 0);
break;
case EXCP_FPE:
- qemu_log("\nFloating point error\n");
+ qemu_log_mask(CPU_LOG_INT, "\nFloating point error\n");
break;
case EXCP_TRAP:
- qemu_log("\nTrap\n");
+ qemu_log_mask(CPU_LOG_INT, "\nTrap\n");
gdbsig = TARGET_SIGTRAP;
break;
case EXCP_NR:
- qemu_log("\nNR\n");
+ qemu_log_mask(CPU_LOG_INT, "\nNR\n");
break;
default:
- qemu_log("\nqemu: unhandled CPU exception %#x - aborting\n",
+ EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
gdbsig = TARGET_SIGILL;
break;
}
@@ -3047,9 +3040,7 @@ void cpu_loop(CPUM68KState *env)
}
break;
default:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
- trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
process_pending_signals(env);
@@ -4241,7 +4232,7 @@ int main(int argc, char **argv, char **envp)
unsigned long tmp;
if (fscanf(fp, "%lu", &tmp) == 1) {
mmap_min_addr = tmp;
- qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
+ qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n", mmap_min_addr);
}
fclose(fp);
}
@@ -4300,7 +4291,7 @@ int main(int argc, char **argv, char **envp)
free(target_environ);
- if (qemu_log_enabled()) {
+ if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
qemu_log("guest_base 0x%lx\n", guest_base);
log_page_dump();
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9d62e027e3..919aa836fa 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -28,8 +28,7 @@
#include "qemu.h"
#include "qemu-common.h"
#include "target_signal.h"
-
-//#define DEBUG_SIGNAL
+#include "trace.h"
static struct target_sigaltstack target_sigaltstack_used = {
.ss_sp = 0,
@@ -444,7 +443,9 @@ static void QEMU_NORETURN force_sig(int target_sig)
TaskState *ts = (TaskState *)cpu->opaque;
int host_sig, core_dumped = 0;
struct sigaction act;
+
host_sig = target_to_host_signal(target_sig);
+ trace_user_force_sig(env, target_sig, host_sig);
gdb_signalled(env, target_sig);
/* dump core if supported by target binary format */
@@ -499,10 +500,7 @@ int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
abi_ulong handler;
int queue;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "queue_signal: sig=%d\n",
- sig);
-#endif
+ trace_user_queue_signal(env, sig);
k = &ts->sigtab[sig - 1];
queue = gdb_queuesig ();
handler = sigact_table[sig - 1]._sa_handler;
@@ -587,9 +585,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
sig = host_to_target_signal(host_signum);
if (sig < 1 || sig > TARGET_NSIG)
return;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "qemu: got signal %d\n", sig);
-#endif
+ trace_user_host_signal(env, host_signum, sig);
host_to_target_siginfo_noswap(&tinfo, info);
if (queue_signal(env, sig, &tinfo) == 1) {
/* interrupt the virtual CPU as soon as possible */
@@ -682,10 +678,6 @@ int do_sigaction(int sig, const struct target_sigaction *act,
if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
return -EINVAL;
k = &sigact_table[sig - 1];
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
- sig, act, oact);
-#endif
if (oact) {
__put_user(k->_sa_handler, &oact->_sa_handler);
__put_user(k->sa_flags, &oact->sa_flags);
@@ -909,6 +901,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -970,6 +963,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -1081,9 +1075,7 @@ long do_sigreturn(CPUX86State *env)
sigset_t set;
int eax, i;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_sigreturn\n");
-#endif
+ trace_user_do_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
/* set blocked signals */
@@ -1115,6 +1107,7 @@ long do_rt_sigreturn(CPUX86State *env)
int eax;
frame_addr = env->regs[R_ESP] - 4;
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
@@ -1318,6 +1311,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
abi_ulong frame_addr, return_addr;
frame_addr = get_sigframe(ka, env);
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
@@ -1377,6 +1371,7 @@ long do_rt_sigreturn(CPUARMState *env)
struct target_rt_sigframe *frame = NULL;
abi_ulong frame_addr = env->xregs[31];
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (frame_addr & 15) {
goto badframe;
}
@@ -1703,6 +1698,7 @@ static void setup_frame_v1(int usig, struct target_sigaction *ka,
abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
int i;
+ trace_user_setup_frame(regs, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
return;
@@ -1724,6 +1720,7 @@ static void setup_frame_v2(int usig, struct target_sigaction *ka,
struct sigframe_v2 *frame;
abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
+ trace_user_setup_frame(regs, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
return;
@@ -1756,6 +1753,7 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
int i;
abi_ulong info_addr, uc_addr;
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
return /* 1 */;
@@ -1796,6 +1794,7 @@ static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
abi_ulong info_addr, uc_addr;
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
return /* 1 */;
@@ -1871,6 +1870,7 @@ static long do_sigreturn_v1(CPUARMState *env)
* not, then the user is trying to mess with us.
*/
frame_addr = env->regs[13];
+ trace_user_do_sigreturn(env, frame_addr);
if (frame_addr & 7) {
goto badframe;
}
@@ -2007,6 +2007,7 @@ static long do_sigreturn_v2(CPUARMState *env)
* not, then the user is trying to mess with us.
*/
frame_addr = env->regs[13];
+ trace_user_do_sigreturn(env, frame_addr);
if (frame_addr & 7) {
goto badframe;
}
@@ -2047,6 +2048,7 @@ static long do_rt_sigreturn_v1(CPUARMState *env)
* not, then the user is trying to mess with us.
*/
frame_addr = env->regs[13];
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (frame_addr & 7) {
goto badframe;
}
@@ -2088,6 +2090,7 @@ static long do_rt_sigreturn_v2(CPUARMState *env)
* not, then the user is trying to mess with us.
*/
frame_addr = env->regs[13];
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (frame_addr & 7) {
goto badframe;
}
@@ -2283,13 +2286,13 @@ static void setup_frame(int sig, struct target_sigaction *ka,
sigframe_size = NF_ALIGNEDSZ;
sf_addr = get_sigframe(ka, env, sigframe_size);
+ trace_user_setup_frame(env, sf_addr);
sf = lock_user(VERIFY_WRITE, sf_addr,
sizeof(struct target_signal_frame), 0);
if (!sf)
goto sigsegv;
- //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
#if 0
if (invalid_frame_pointer(sf, sigframe_size))
goto sigill_and_return;
@@ -2356,7 +2359,6 @@ sigill_and_return:
force_sig(TARGET_SIGILL);
#endif
sigsegv:
- //fprintf(stderr, "force_sig\n");
unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
force_sig(TARGET_SIGSEGV);
}
@@ -2378,13 +2380,9 @@ long do_sigreturn(CPUSPARCState *env)
int err=0, i;
sf_addr = env->regwptr[UREG_FP];
+ trace_user_do_sigreturn(env, sf_addr);
if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
goto segv_and_exit;
-#if 0
- fprintf(stderr, "sigreturn\n");
- fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
-#endif
- //cpu_dump_state(env, stderr, fprintf, 0);
/* 1. Make sure we are not getting garbage from the user */
@@ -2443,6 +2441,7 @@ segv_and_exit:
long do_rt_sigreturn(CPUSPARCState *env)
{
+ trace_user_do_rt_sigreturn(env, 0);
fprintf(stderr, "do_rt_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
@@ -2902,6 +2901,7 @@ static void setup_frame(int sig, struct target_sigaction * ka,
int i;
frame_addr = get_sigframe(ka, regs, sizeof(*frame));
+ trace_user_setup_frame(regs, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -2948,10 +2948,8 @@ long do_sigreturn(CPUMIPSState *regs)
target_sigset_t target_set;
int i;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_sigreturn\n");
-#endif
frame_addr = regs->active_tc.gpr[29];
+ trace_user_do_sigreturn(regs, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -2998,6 +2996,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -3055,10 +3054,8 @@ long do_rt_sigreturn(CPUMIPSState *env)
abi_ulong frame_addr;
sigset_t blocked;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_rt_sigreturn\n");
-#endif
frame_addr = env->active_tc.gpr[29];
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -3216,6 +3213,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int err = 0;
frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
+ trace_user_setup_frame(regs, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -3265,6 +3263,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
int err = 0;
frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
+ trace_user_setup_rt_frame(regs, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -3325,10 +3324,8 @@ long do_sigreturn(CPUSH4State *regs)
int i;
int err = 0;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_sigreturn\n");
-#endif
frame_addr = regs->gregs[15];
+ trace_user_do_sigreturn(regs, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -3361,10 +3358,8 @@ long do_rt_sigreturn(CPUSH4State *regs)
sigset_t blocked;
target_ulong r0;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_rt_sigreturn\n");
-#endif
frame_addr = regs->gregs[15];
+ trace_user_do_rt_sigreturn(regs, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -3514,6 +3509,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof *frame);
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto badframe;
@@ -3579,6 +3575,7 @@ long do_sigreturn(CPUMBState *env)
int i;
frame_addr = env->regs[R_SP];
+ trace_user_do_sigreturn(env, frame_addr);
/* Make sure the guest isn't playing games. */
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
goto badframe;
@@ -3604,6 +3601,7 @@ long do_sigreturn(CPUMBState *env)
long do_rt_sigreturn(CPUMBState *env)
{
+ trace_user_do_rt_sigreturn(env, 0);
fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
@@ -3693,6 +3691,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(env, sizeof *frame);
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto badframe;
@@ -3746,6 +3745,7 @@ long do_sigreturn(CPUCRISState *env)
int i;
frame_addr = env->regs[R_SP];
+ trace_user_do_sigreturn(env, frame_addr);
/* Make sure the guest isn't playing games. */
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
goto badframe;
@@ -3767,6 +3767,7 @@ long do_sigreturn(CPUCRISState *env)
long do_rt_sigreturn(CPUCRISState *env)
{
+ trace_user_do_rt_sigreturn(env, 0);
fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
@@ -3911,6 +3912,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
abi_ulong info_addr, uc_addr;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
@@ -3972,14 +3974,15 @@ give_sigsegv:
long do_sigreturn(CPUOpenRISCState *env)
{
-
- qemu_log("do_sigreturn: not implemented\n");
+ trace_user_do_sigreturn(env, 0);
+ fprintf(stderr, "do_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
long do_rt_sigreturn(CPUOpenRISCState *env)
{
- qemu_log("do_rt_sigreturn: not implemented\n");
+ trace_user_do_rt_sigreturn(env, 0);
+ fprintf(stderr, "do_rt_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
/* TARGET_OPENRISC */
@@ -4102,13 +4105,11 @@ static void setup_frame(int sig, struct target_sigaction *ka,
abi_ulong frame_addr;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
- qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
- (unsigned long long)frame_addr);
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
- qemu_log("%s: 1\n", __FUNCTION__);
__put_user(set->sig[0], &frame->sc.oldmask[0]);
save_sigregs(env, &frame->sregs);
@@ -4149,7 +4150,6 @@ static void setup_frame(int sig, struct target_sigaction *ka,
return;
give_sigsegv:
- qemu_log("%s: give_sigsegv\n", __FUNCTION__);
force_sig(TARGET_SIGSEGV);
}
@@ -4162,13 +4162,11 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
abi_ulong frame_addr;
frame_addr = get_sigframe(ka, env, sizeof *frame);
- qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
- (unsigned long long)frame_addr);
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
- qemu_log("%s: 1\n", __FUNCTION__);
tswap_siginfo(&frame->info, info);
/* Create the ucontext. */
@@ -4207,7 +4205,6 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
return;
give_sigsegv:
- qemu_log("%s: give_sigsegv\n", __FUNCTION__);
force_sig(TARGET_SIGSEGV);
}
@@ -4222,9 +4219,8 @@ restore_sigregs(CPUS390XState *env, target_sigregs *sc)
}
__get_user(env->psw.mask, &sc->regs.psw.mask);
- qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
- __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
- (unsigned long long)env->psw.addr);
+ trace_user_s390x_restore_sigregs(env, (unsigned long long)sc->regs.psw.addr,
+ (unsigned long long)env->psw.addr);
__get_user(env->psw.addr, &sc->regs.psw.addr);
/* FIXME: 31-bit -> | PSW_ADDR_AMODE */
@@ -4242,11 +4238,10 @@ long do_sigreturn(CPUS390XState *env)
{
sigframe *frame;
abi_ulong frame_addr = env->regs[15];
- qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
- (unsigned long long)frame_addr);
target_sigset_t target_set;
sigset_t set;
+ trace_user_do_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
goto badframe;
}
@@ -4271,10 +4266,9 @@ long do_rt_sigreturn(CPUS390XState *env)
{
rt_sigframe *frame;
abi_ulong frame_addr = env->regs[15];
- qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
- (unsigned long long)frame_addr);
sigset_t set;
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
goto badframe;
}
@@ -4659,6 +4653,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
#endif
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
goto sigsegv;
sc = &frame->sctx;
@@ -4723,7 +4718,6 @@ static void setup_frame(int sig, struct target_sigaction *ka,
sigsegv:
unlock_user_struct(frame, frame_addr, 1);
- qemu_log("segfaulting from setup_frame\n");
force_sig(TARGET_SIGSEGV);
}
@@ -4819,7 +4813,6 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1);
- qemu_log("segfaulting from setup_rt_frame\n");
force_sig(TARGET_SIGSEGV);
}
@@ -4857,7 +4850,6 @@ long do_sigreturn(CPUPPCState *env)
sigsegv:
unlock_user_struct(sr, sr_addr, 1);
unlock_user_struct(sc, sc_addr, 1);
- qemu_log("segfaulting from do_sigreturn\n");
force_sig(TARGET_SIGSEGV);
return 0;
}
@@ -4913,7 +4905,6 @@ long do_rt_sigreturn(CPUPPCState *env)
sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1);
- qemu_log("segfaulting from do_rt_sigreturn\n");
force_sig(TARGET_SIGSEGV);
return 0;
}
@@ -5037,6 +5028,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof *frame);
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -5153,6 +5145,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof *frame);
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -5220,6 +5213,7 @@ long do_sigreturn(CPUM68KState *env)
sigset_t set;
int d0, i;
+ trace_user_do_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -5254,6 +5248,7 @@ long do_rt_sigreturn(CPUM68KState *env)
sigset_t set;
int d0;
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -5393,6 +5388,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int err = 0;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
@@ -5437,6 +5433,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
int i, err = 0;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
@@ -5515,6 +5512,7 @@ long do_rt_sigreturn(CPUAlphaState *env)
struct target_rt_sigframe *frame;
sigset_t set;
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
goto badframe;
}
@@ -5622,6 +5620,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
unsigned long restorer;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
@@ -5672,6 +5671,7 @@ long do_rt_sigreturn(CPUTLGState *env)
struct target_rt_sigframe *frame;
sigset_t set;
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
goto badframe;
}
@@ -5750,9 +5750,7 @@ void process_pending_signals(CPUArchState *cpu_env)
return;
handle_signal:
-#ifdef DEBUG_SIGNAL
- fprintf(stderr, "qemu: process signal %d\n", sig);
-#endif
+ trace_user_handle_signal(cpu_env, sig);
/* dequeue signal */
q = k->first;
k->first = q->next;
diff --git a/memory.c b/memory.c
index e193658fc7..93bd8ed7bc 100644
--- a/memory.c
+++ b/memory.c
@@ -18,12 +18,14 @@
#include "exec/ioport.h"
#include "qapi/visitor.h"
#include "qemu/bitops.h"
+#include "qemu/error-report.h"
#include "qom/object.h"
#include "trace.h"
#include <assert.h>
#include "exec/memory-internal.h"
#include "exec/ram_addr.h"
+#include "sysemu/kvm.h"
#include "sysemu/sysemu.h"
//#define DEBUG_UNASSIGNED
@@ -859,11 +861,6 @@ static void memory_region_destructor_ram(MemoryRegion *mr)
qemu_ram_free(mr->ram_addr);
}
-static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
-{
- qemu_ram_free_from_ptr(mr->ram_addr);
-}
-
static void memory_region_destructor_rom_device(MemoryRegion *mr)
{
qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
@@ -908,20 +905,22 @@ void memory_region_init(MemoryRegion *mr,
const char *name,
uint64_t size)
{
- if (!owner) {
- owner = container_get(qdev_get_machine(), "/unattached");
- }
-
object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION);
mr->size = int128_make64(size);
if (size == UINT64_MAX) {
mr->size = int128_2_64();
}
mr->name = g_strdup(name);
+ mr->owner = owner;
if (name) {
char *escaped_name = memory_region_escape_name(name);
char *name_array = g_strdup_printf("%s[*]", escaped_name);
+
+ if (!owner) {
+ owner = container_get(qdev_get_machine(), "/unattached");
+ }
+
object_property_add_child(owner, name_array, OBJECT(mr), &error_abort);
object_unref(OBJECT(mr));
g_free(name_array);
@@ -1141,6 +1140,32 @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
return r;
}
+/* Return true if an eventfd was signalled */
+static bool memory_region_dispatch_write_eventfds(MemoryRegion *mr,
+ hwaddr addr,
+ uint64_t data,
+ unsigned size,
+ MemTxAttrs attrs)
+{
+ MemoryRegionIoeventfd ioeventfd = {
+ .addr = addrrange_make(int128_make64(addr), int128_make64(size)),
+ .data = data,
+ };
+ unsigned i;
+
+ for (i = 0; i < mr->ioeventfd_nb; i++) {
+ ioeventfd.match_data = mr->ioeventfds[i].match_data;
+ ioeventfd.e = mr->ioeventfds[i].e;
+
+ if (memory_region_ioeventfd_equal(ioeventfd, mr->ioeventfds[i])) {
+ event_notifier_set(ioeventfd.e);
+ return true;
+ }
+ }
+
+ return false;
+}
+
MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
hwaddr addr,
uint64_t data,
@@ -1154,6 +1179,11 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
adjust_endianness(mr, &data, size);
+ if ((!kvm_eventfds_enabled()) &&
+ memory_region_dispatch_write_eventfds(mr, addr, data, size, attrs)) {
+ return MEMTX_OK;
+ }
+
if (mr->ops->write) {
return access_with_adjusted_size(addr, &data, size,
mr->ops->impl.min_access_size,
@@ -1246,7 +1276,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
memory_region_init(mr, owner, name, size);
mr->ram = true;
mr->terminates = true;
- mr->destructor = memory_region_destructor_ram_from_ptr;
+ mr->destructor = memory_region_destructor_ram;
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
/* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL. */
@@ -1341,24 +1371,18 @@ void memory_region_ref(MemoryRegion *mr)
* The memory region is a child of its owner. As long as the
* owner doesn't call unparent itself on the memory region,
* ref-ing the owner will also keep the memory region alive.
- * Memory regions without an owner are supposed to never go away,
- * but we still ref/unref them for debugging purposes.
+ * Memory regions without an owner are supposed to never go away;
+ * we do not ref/unref them because it slows down DMA sensibly.
*/
- Object *obj = OBJECT(mr);
- if (obj && obj->parent) {
- object_ref(obj->parent);
- } else {
- object_ref(obj);
+ if (mr && mr->owner) {
+ object_ref(mr->owner);
}
}
void memory_region_unref(MemoryRegion *mr)
{
- Object *obj = OBJECT(mr);
- if (obj && obj->parent) {
- object_unref(obj->parent);
- } else {
- object_unref(obj);
+ if (mr && mr->owner) {
+ object_unref(mr->owner);
}
}
@@ -1379,11 +1403,6 @@ const char *memory_region_name(const MemoryRegion *mr)
return mr->name;
}
-bool memory_region_is_ram(MemoryRegion *mr)
-{
- return mr->ram;
-}
-
bool memory_region_is_skip_dump(MemoryRegion *mr)
{
return mr->skip_dump;
@@ -1403,16 +1422,6 @@ bool memory_region_is_logging(MemoryRegion *mr, uint8_t client)
return memory_region_get_dirty_log_mask(mr) & (1 << client);
}
-bool memory_region_is_rom(MemoryRegion *mr)
-{
- return mr->ram && mr->readonly;
-}
-
-bool memory_region_is_iommu(MemoryRegion *mr)
-{
- return mr->iommu_ops;
-}
-
void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n)
{
notifier_list_add(&mr->iommu_notify, n);
@@ -1549,13 +1558,19 @@ int memory_region_get_fd(MemoryRegion *mr)
void *memory_region_get_ram_ptr(MemoryRegion *mr)
{
- if (mr->alias) {
- return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
- }
+ void *ptr;
+ uint64_t offset = 0;
+ rcu_read_lock();
+ while (mr->alias) {
+ offset += mr->alias_offset;
+ mr = mr->alias;
+ }
assert(mr->ram_addr != RAM_ADDR_INVALID);
+ ptr = qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
+ rcu_read_unlock();
- return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
+ return ptr + offset;
}
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp)
@@ -1672,6 +1687,8 @@ void memory_region_clear_global_locking(MemoryRegion *mr)
mr->global_locking = false;
}
+static bool userspace_eventfd_warning;
+
void memory_region_add_eventfd(MemoryRegion *mr,
hwaddr addr,
unsigned size,
@@ -1688,6 +1705,13 @@ void memory_region_add_eventfd(MemoryRegion *mr,
};
unsigned i;
+ if (kvm_enabled() && (!(kvm_eventfds_enabled() ||
+ userspace_eventfd_warning))) {
+ userspace_eventfd_warning = true;
+ error_report("Using eventfd without MMIO binding in KVM. "
+ "Suboptimal performance expected");
+ }
+
if (size) {
adjust_endianness(mr, &mrfd.data, size);
}
@@ -1889,11 +1913,6 @@ void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset)
memory_region_transaction_commit();
}
-ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
-{
- return mr->ram_addr;
-}
-
uint64_t memory_region_get_alignment(const MemoryRegion *mr)
{
return mr->align;
diff --git a/qapi-schema.json b/qapi-schema.json
index f014a80f72..516b14526b 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3102,11 +3102,14 @@
#
# @in: #optional The name of the input file
# @out: The name of the output file
+# @append: #optional Open the file in append mode (default false to
+# truncate) (Since 2.6)
#
# Since: 1.4
##
{ 'struct': 'ChardevFile', 'data': { '*in' : 'str',
- 'out' : 'str' } }
+ 'out' : 'str',
+ '*append': 'bool' } }
##
# @ChardevHostdev:
diff --git a/qapi/common.json b/qapi/common.json
index 6fb40e7a15..9353a7b377 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -115,3 +115,19 @@
##
{ 'enum': 'OnOffAuto',
'data': [ 'auto', 'on', 'off' ] }
+
+##
+# @OnOffSplit
+#
+# An enumeration of three values: on, off, and split
+#
+# @on: Enabled
+#
+# @off: Disabled
+#
+# @split: Mixed
+#
+# Since: 2.6
+##
+{ 'enum': 'OnOffSplit',
+ 'data': [ 'on', 'off', 'split' ] }
diff --git a/qemu-char.c b/qemu-char.c
index 2969c44e84..66703e3f0a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3484,6 +3484,9 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
}
backend->u.file = g_new0(ChardevFile, 1);
backend->u.file->out = g_strdup(path);
+
+ backend->u.file->has_append = true;
+ backend->u.file->append = qemu_opt_get_bool(opts, "append", false);
}
static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
@@ -4041,6 +4044,9 @@ QemuOptsList qemu_chardev_opts = {
},{
.name = "chardev",
.type = QEMU_OPT_STRING,
+ },{
+ .name = "append",
+ .type = QEMU_OPT_BOOL,
},
{ /* end of list */ }
},
@@ -4101,7 +4107,13 @@ static CharDriverState *qmp_chardev_open_file(const char *id,
ChardevFile *file = backend->u.file;
int flags, in = -1, out;
- flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY;
+ flags = O_WRONLY | O_CREAT | O_BINARY;
+ if (file->has_append && file->append) {
+ flags |= O_APPEND;
+ } else {
+ flags |= O_TRUNC;
+ }
+
out = qmp_chardev_open_file_source(file->out, flags, errp);
if (out < 0) {
return NULL;
diff --git a/qemu-log.c b/qemu-log.c
index 7cb01a802b..901b93087d 100644
--- a/qemu-log.c
+++ b/qemu-log.c
@@ -117,6 +117,8 @@ const QEMULogItem qemu_log_items[] = {
{ LOG_GUEST_ERROR, "guest_errors",
"log when the guest OS does something invalid (eg accessing a\n"
"non-existent register)" },
+ { CPU_LOG_PAGE, "page",
+ "dump pages at beginning of user mode emulation" },
{ CPU_LOG_TB_NOCHAIN, "nochain",
"do not chain compiled TBs so that \"exec\" and \"cpu\" show\n"
"complete traces" },
diff --git a/qemu-options.hx b/qemu-options.hx
index 0eea4ee9e9..5affc82e4c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -33,6 +33,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" property accel=accel1[:accel2[:...]] selects accelerator\n"
" supported accelerators are kvm, xen, tcg (default: tcg)\n"
" kernel_irqchip=on|off controls accelerated irqchip support\n"
+ " kernel_irqchip=on|off|split controls accelerated irqchip support (default=off)\n"
" vmport=on|off|auto controls emulation of vmport (default: auto)\n"
" kvm_shadow_mem=size of KVM shadow MMU\n"
" dump-guest-core=on|off include guest memory in a core dump (default=on)\n"
@@ -55,7 +56,7 @@ kvm, xen, or tcg can be available. By default, tcg is used. If there is more
than one accelerator specified, the next one is used if the previous one fails
to initialize.
@item kernel_irqchip=on|off
-Enables in-kernel irqchip support for the chosen accelerator when available.
+Controls in-kernel irqchip support for the chosen accelerator when available.
@item gfx_passthru=on|off
Enables IGD GFX passthrough support for the chosen machine when available.
@item vmport=on|off|auto
diff --git a/scripts/coverity-model.c b/scripts/coverity-model.c
index 617f67d716..ee5bf9d078 100644
--- a/scripts/coverity-model.c
+++ b/scripts/coverity-model.c
@@ -236,6 +236,23 @@ void *g_try_realloc(void *ptr, size_t size)
return g_try_realloc_n(ptr, 1, size);
}
+/* Other memory allocation functions */
+
+void *g_memdup(const void *ptr, unsigned size)
+{
+ unsigned char *dup;
+ unsigned i;
+
+ if (!ptr) {
+ return NULL;
+ }
+
+ dup = g_malloc(size);
+ for (i = 0; i < size; i++)
+ dup[i] = ((unsigned char *)ptr)[i];
+ return dup;
+}
+
/*
* GLib string allocation functions
*/
@@ -325,6 +342,15 @@ char *g_strconcat(const char *s, ...)
/* Other glib functions */
+typedef struct pollfd GPollFD;
+
+int poll();
+
+int g_poll (GPollFD *fds, unsigned nfds, int timeout)
+{
+ return poll(fds, nfds, timeout);
+}
+
typedef struct _GIOChannel GIOChannel;
GIOChannel *g_io_channel_unix_new(int fd)
{
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 096d0900c3..ff5b0c7033 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -36,6 +36,7 @@ cp_portable() {
-e 'linux/types' \
-e 'stdint' \
-e 'linux/if_ether' \
+ -e 'input-event-codes' \
-e 'sys/' \
> /dev/null
then
@@ -48,6 +49,7 @@ cp_portable() {
-e 's/__s\([0-9][0-9]*\)/int\1_t/g' \
-e 's/__le\([0-9][0-9]*\)/uint\1_t/g' \
-e 's/__be\([0-9][0-9]*\)/uint\1_t/g' \
+ -e 's/"\(input-event-codes\.h\)"/"standard-headers\/linux\/\1"/' \
-e 's/<linux\/\([^>]*\)>/"standard-headers\/linux\/\1"/' \
-e 's/__bitwise__//' \
-e 's/__attribute__((packed))/QEMU_PACKED/' \
@@ -128,6 +130,7 @@ EOF
rm -rf "$output/include/standard-headers/linux"
mkdir -p "$output/include/standard-headers/linux"
for i in "$tmpdir"/include/linux/*virtio*.h "$tmpdir/include/linux/input.h" \
+ "$tmpdir/include/linux/input-event-codes.h" \
"$tmpdir/include/linux/pci_regs.h"; do
cp_portable "$i" "$output/include/standard-headers/linux"
done
diff --git a/stubs/kvm.c b/stubs/kvm.c
index e7c60b6e0c..828b824f2c 100644
--- a/stubs/kvm.c
+++ b/stubs/kvm.c
@@ -1,7 +1,7 @@
#include "qemu-common.h"
#include "sysemu/kvm.h"
-int kvm_arch_irqchip_create(KVMState *s)
+int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
{
return 0;
}
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 84974bbd32..eca3a0037d 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -25,6 +25,7 @@
#include "internals.h"
#include "hw/arm/arm.h"
#include "exec/memattrs.h"
+#include "hw/boards.h"
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
@@ -578,8 +579,13 @@ void kvm_arch_init_irq_routing(KVMState *s)
{
}
-int kvm_arch_irqchip_create(KVMState *s)
+int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
{
+ if (machine_kernel_irqchip_split(ms)) {
+ perror("-machine kernel_irqchip=split is not supported on ARM.");
+ exit(1);
+ }
+
/* If we can create the VGIC using the newer device control API, we
* let the device do this when it initializes itself, otherwise we
* fall back to the old API */
diff --git a/target-cris/helper.h b/target-cris/helper.h
index 0b383b25a4..ff3595641a 100644
--- a/target-cris/helper.h
+++ b/target-cris/helper.h
@@ -1,7 +1,6 @@
DEF_HELPER_2(raise_exception, void, env, i32)
DEF_HELPER_2(tlb_flush_pid, void, env, i32)
DEF_HELPER_2(spc_write, void, env, i32)
-DEF_HELPER_3(dump, void, i32, i32, i32)
DEF_HELPER_1(rfe, void, env)
DEF_HELPER_1(rfn, void, env)
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index 5c0c14d992..22966771e9 100644
--- a/target-cris/op_helper.c
+++ b/target-cris/op_helper.c
@@ -91,11 +91,6 @@ void helper_spc_write(CPUCRISState *env, uint32_t new_spc)
#endif
}
-void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2)
-{
- qemu_log("%s: a0=%x a1=%x\n", __func__, a0, a1);
-}
-
/* Used by the tlb decoder. */
#define EXTRACT_FIELD(src, start, end) \
(((src) >> start) & ((1 << (end - start + 1)) - 1))
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 2d710cc108..24299314d0 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -130,8 +130,10 @@ typedef struct DisasContext {
static void gen_BUG(DisasContext *dc, const char *file, int line)
{
- printf("BUG: pc=%x %s %d\n", dc->pc, file, line);
- qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
+ fprintf(stderr, "BUG: pc=%x %s %d\n", dc->pc, file, line);
+ if (qemu_log_separate()) {
+ qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
+ }
cpu_abort(CPU(dc->cpu), "%s:%d\n", file, line);
}
@@ -777,7 +779,7 @@ static void cris_alu_op_exec(DisasContext *dc, int op,
t_gen_subx_carry(dc, dst);
break;
default:
- qemu_log("illegal ALU op.\n");
+ qemu_log_mask(LOG_GUEST_ERROR, "illegal ALU op.\n");
BUG();
break;
}
diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
index 3ab1c398e0..df20bdc5f1 100644
--- a/target-cris/translate_v10.c
+++ b/target-cris/translate_v10.c
@@ -58,7 +58,7 @@ static inline int dec10_size(unsigned int size)
static inline void cris_illegal_insn(DisasContext *dc)
{
- qemu_log("illegal insn at pc=%x\n", dc->pc);
+ qemu_log_mask(LOG_GUEST_ERROR, "illegal insn at pc=%x\n", dc->pc);
t_gen_raise_exception(EXCP_BREAK);
}
diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs
index 437d9975b9..2255f46a9e 100644
--- a/target-i386/Makefile.objs
+++ b/target-i386/Makefile.objs
@@ -3,5 +3,5 @@ obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o
obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
obj-y += gdbstub.o
obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o
-obj-$(CONFIG_KVM) += kvm.o
+obj-$(CONFIG_KVM) += kvm.o hyperv.o
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index e3bfe9d07e..5f9d960b25 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -94,6 +94,8 @@ typedef struct X86CPU {
bool hyperv_reset;
bool hyperv_vpindex;
bool hyperv_runtime;
+ bool hyperv_synic;
+ bool hyperv_stimer;
bool check_cpuid;
bool enforce_cpuid;
bool expose_kvm;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 11e5e39a75..0d447b5690 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2743,7 +2743,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
APICCommonState *apic;
const char *apic_type = "apic";
- if (kvm_irqchip_in_kernel()) {
+ if (kvm_apic_in_kernel()) {
apic_type = "kvm-apic";
} else if (xen_enabled()) {
apic_type = "xen-apic";
@@ -3146,6 +3146,8 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false),
DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
+ DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
+ DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 84edfd0d8a..595891e78d 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -920,6 +920,13 @@ typedef struct CPUX86State {
uint64_t msr_hv_tsc;
uint64_t msr_hv_crash_params[HV_X64_MSR_CRASH_PARAMS];
uint64_t msr_hv_runtime;
+ uint64_t msr_hv_synic_control;
+ uint64_t msr_hv_synic_version;
+ uint64_t msr_hv_synic_evt_page;
+ uint64_t msr_hv_synic_msg_page;
+ uint64_t msr_hv_synic_sint[HV_SYNIC_SINT_COUNT];
+ uint64_t msr_hv_stimer_config[HV_SYNIC_STIMER_COUNT];
+ uint64_t msr_hv_stimer_count[HV_SYNIC_STIMER_COUNT];
/* exception/interrupt handling */
int error_code;
diff --git a/target-i386/hyperv.c b/target-i386/hyperv.c
new file mode 100644
index 0000000000..e79b173a81
--- /dev/null
+++ b/target-i386/hyperv.c
@@ -0,0 +1,127 @@
+/*
+ * QEMU KVM Hyper-V support
+ *
+ * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
+ *
+ * Authors:
+ * Andrey Smetanin <asmetanin@virtuozzo.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hyperv.h"
+#include "standard-headers/asm-x86/hyperv.h"
+
+int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit)
+{
+ CPUX86State *env = &cpu->env;
+
+ switch (exit->type) {
+ case KVM_EXIT_HYPERV_SYNIC:
+ if (!cpu->hyperv_synic) {
+ return -1;
+ }
+
+ /*
+ * For now just track changes in SynIC control and msg/evt pages msr's.
+ * When SynIC messaging/events processing will be added in future
+ * here we will do messages queues flushing and pages remapping.
+ */
+ switch (exit->u.synic.msr) {
+ case HV_X64_MSR_SCONTROL:
+ env->msr_hv_synic_control = exit->u.synic.control;
+ break;
+ case HV_X64_MSR_SIMP:
+ env->msr_hv_synic_msg_page = exit->u.synic.msg_page;
+ break;
+ case HV_X64_MSR_SIEFP:
+ env->msr_hv_synic_evt_page = exit->u.synic.evt_page;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+static void kvm_hv_sint_ack_handler(EventNotifier *notifier)
+{
+ HvSintRoute *sint_route = container_of(notifier, HvSintRoute,
+ sint_ack_notifier);
+ event_notifier_test_and_clear(notifier);
+ if (sint_route->sint_ack_clb) {
+ sint_route->sint_ack_clb(sint_route);
+ }
+}
+
+HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint,
+ HvSintAckClb sint_ack_clb)
+{
+ HvSintRoute *sint_route;
+ int r, gsi;
+
+ sint_route = g_malloc0(sizeof(*sint_route));
+ r = event_notifier_init(&sint_route->sint_set_notifier, false);
+ if (r) {
+ goto err;
+ }
+
+ r = event_notifier_init(&sint_route->sint_ack_notifier, false);
+ if (r) {
+ goto err_sint_set_notifier;
+ }
+
+ event_notifier_set_handler(&sint_route->sint_ack_notifier,
+ kvm_hv_sint_ack_handler);
+
+ gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vcpu_id, sint);
+ if (gsi < 0) {
+ goto err_gsi;
+ }
+
+ r = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state,
+ &sint_route->sint_set_notifier,
+ &sint_route->sint_ack_notifier, gsi);
+ if (r) {
+ goto err_irqfd;
+ }
+ sint_route->gsi = gsi;
+ sint_route->sint_ack_clb = sint_ack_clb;
+ sint_route->vcpu_id = vcpu_id;
+ sint_route->sint = sint;
+
+ return sint_route;
+
+err_irqfd:
+ kvm_irqchip_release_virq(kvm_state, gsi);
+err_gsi:
+ event_notifier_set_handler(&sint_route->sint_ack_notifier, NULL);
+ event_notifier_cleanup(&sint_route->sint_ack_notifier);
+err_sint_set_notifier:
+ event_notifier_cleanup(&sint_route->sint_set_notifier);
+err:
+ g_free(sint_route);
+
+ return NULL;
+}
+
+void kvm_hv_sint_route_destroy(HvSintRoute *sint_route)
+{
+ kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state,
+ &sint_route->sint_set_notifier,
+ sint_route->gsi);
+ kvm_irqchip_release_virq(kvm_state, sint_route->gsi);
+ event_notifier_set_handler(&sint_route->sint_ack_notifier, NULL);
+ event_notifier_cleanup(&sint_route->sint_ack_notifier);
+ event_notifier_cleanup(&sint_route->sint_set_notifier);
+ g_free(sint_route);
+}
+
+int kvm_hv_sint_route_set_sint(HvSintRoute *sint_route)
+{
+ return event_notifier_set(&sint_route->sint_set_notifier);
+}
diff --git a/target-i386/hyperv.h b/target-i386/hyperv.h
new file mode 100644
index 0000000000..b26201f8b9
--- /dev/null
+++ b/target-i386/hyperv.h
@@ -0,0 +1,42 @@
+/*
+ * QEMU KVM Hyper-V support
+ *
+ * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
+ *
+ * Authors:
+ * Andrey Smetanin <asmetanin@virtuozzo.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef HYPERV_I386_H
+#define HYPERV_I386_H
+
+#include "cpu.h"
+#include "sysemu/kvm.h"
+#include "qemu/event_notifier.h"
+
+typedef struct HvSintRoute HvSintRoute;
+typedef void (*HvSintAckClb)(HvSintRoute *sint_route);
+
+struct HvSintRoute {
+ uint32_t sint;
+ uint32_t vcpu_id;
+ int gsi;
+ EventNotifier sint_set_notifier;
+ EventNotifier sint_ack_notifier;
+ HvSintAckClb sint_ack_clb;
+};
+
+int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit);
+
+HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint,
+ HvSintAckClb sint_ack_clb);
+
+void kvm_hv_sint_route_destroy(HvSintRoute *sint_route);
+
+int kvm_hv_sint_route_set_sint(HvSintRoute *sint_route);
+
+#endif
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 6dc9846398..ab65a6ebe5 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -25,6 +25,8 @@
#include "sysemu/kvm_int.h"
#include "kvm_i386.h"
#include "cpu.h"
+#include "hyperv.h"
+
#include "exec/gdbstub.h"
#include "qemu/host-utils.h"
#include "qemu/config-file.h"
@@ -33,9 +35,11 @@
#include "hw/i386/apic.h"
#include "hw/i386/apic_internal.h"
#include "hw/i386/apic-msidef.h"
+
#include "exec/ioport.h"
#include "standard-headers/asm-x86/hyperv.h"
#include "hw/pci/pci.h"
+#include "hw/pci/msi.h"
#include "migration/migration.h"
#include "exec/memattrs.h"
@@ -86,6 +90,8 @@ static bool has_msr_hv_crash;
static bool has_msr_hv_reset;
static bool has_msr_hv_vpindex;
static bool has_msr_hv_runtime;
+static bool has_msr_hv_synic;
+static bool has_msr_hv_stimer;
static bool has_msr_mtrr;
static bool has_msr_xss;
@@ -521,7 +527,9 @@ static bool hyperv_enabled(X86CPU *cpu)
cpu->hyperv_crash ||
cpu->hyperv_reset ||
cpu->hyperv_vpindex ||
- cpu->hyperv_runtime);
+ cpu->hyperv_runtime ||
+ cpu->hyperv_synic ||
+ cpu->hyperv_stimer);
}
static Error *invtsc_mig_blocker;
@@ -610,6 +618,28 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (cpu->hyperv_runtime && has_msr_hv_runtime) {
c->eax |= HV_X64_MSR_VP_RUNTIME_AVAILABLE;
}
+ if (cpu->hyperv_synic) {
+ int sint;
+
+ if (!has_msr_hv_synic ||
+ kvm_vcpu_enable_cap(cs, KVM_CAP_HYPERV_SYNIC, 0)) {
+ fprintf(stderr, "Hyper-V SynIC is not supported by kernel\n");
+ return -ENOSYS;
+ }
+
+ c->eax |= HV_X64_MSR_SYNIC_AVAILABLE;
+ env->msr_hv_synic_version = HV_SYNIC_VERSION_1;
+ for (sint = 0; sint < ARRAY_SIZE(env->msr_hv_synic_sint); sint++) {
+ env->msr_hv_synic_sint[sint] = HV_SYNIC_SINT_MASKED;
+ }
+ }
+ if (cpu->hyperv_stimer) {
+ if (!has_msr_hv_stimer) {
+ fprintf(stderr, "Hyper-V timers aren't supported by kernel\n");
+ return -ENOSYS;
+ }
+ c->eax |= HV_X64_MSR_SYNTIMER_AVAILABLE;
+ }
c = &cpuid_data.entries[cpuid_i++];
c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
if (cpu->hyperv_relaxed_timing) {
@@ -956,6 +986,14 @@ static int kvm_get_supported_msrs(KVMState *s)
has_msr_hv_runtime = true;
continue;
}
+ if (kvm_msr_list->indices[i] == HV_X64_MSR_SCONTROL) {
+ has_msr_hv_synic = true;
+ continue;
+ }
+ if (kvm_msr_list->indices[i] == HV_X64_MSR_STIMER0_CONFIG) {
+ has_msr_hv_stimer = true;
+ continue;
+ }
}
}
@@ -1107,7 +1145,7 @@ static void set_seg(struct kvm_segment *lhs, const SegmentCache *rhs)
lhs->l = (flags >> DESC_L_SHIFT) & 1;
lhs->g = (flags & DESC_G_MASK) != 0;
lhs->avl = (flags & DESC_AVL_MASK) != 0;
- lhs->unusable = 0;
+ lhs->unusable = !lhs->present;
lhs->padding = 0;
}
@@ -1116,14 +1154,18 @@ static void get_seg(SegmentCache *lhs, const struct kvm_segment *rhs)
lhs->selector = rhs->selector;
lhs->base = rhs->base;
lhs->limit = rhs->limit;
- lhs->flags = (rhs->type << DESC_TYPE_SHIFT) |
- (rhs->present * DESC_P_MASK) |
- (rhs->dpl << DESC_DPL_SHIFT) |
- (rhs->db << DESC_B_SHIFT) |
- (rhs->s * DESC_S_MASK) |
- (rhs->l << DESC_L_SHIFT) |
- (rhs->g * DESC_G_MASK) |
- (rhs->avl * DESC_AVL_MASK);
+ if (rhs->unusable) {
+ lhs->flags = 0;
+ } else {
+ lhs->flags = (rhs->type << DESC_TYPE_SHIFT) |
+ (rhs->present * DESC_P_MASK) |
+ (rhs->dpl << DESC_DPL_SHIFT) |
+ (rhs->db << DESC_B_SHIFT) |
+ (rhs->s * DESC_S_MASK) |
+ (rhs->l << DESC_L_SHIFT) |
+ (rhs->g * DESC_G_MASK) |
+ (rhs->avl * DESC_AVL_MASK);
+ }
}
static void kvm_getput_reg(__u64 *kvm_reg, target_ulong *qemu_reg, int set)
@@ -1517,6 +1559,36 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_VP_RUNTIME,
env->msr_hv_runtime);
}
+ if (cpu->hyperv_synic) {
+ int j;
+
+ kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SCONTROL,
+ env->msr_hv_synic_control);
+ kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SVERSION,
+ env->msr_hv_synic_version);
+ kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SIEFP,
+ env->msr_hv_synic_evt_page);
+ kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SIMP,
+ env->msr_hv_synic_msg_page);
+
+ for (j = 0; j < ARRAY_SIZE(env->msr_hv_synic_sint); j++) {
+ kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SINT0 + j,
+ env->msr_hv_synic_sint[j]);
+ }
+ }
+ if (has_msr_hv_stimer) {
+ int j;
+
+ for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_config); j++) {
+ kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_STIMER0_CONFIG + j*2,
+ env->msr_hv_stimer_config[j]);
+ }
+
+ for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_count); j++) {
+ kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_STIMER0_COUNT + j*2,
+ env->msr_hv_stimer_count[j]);
+ }
+ }
if (has_msr_mtrr) {
kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype);
kvm_msr_entry_set(&msrs[n++],
@@ -1885,6 +1957,25 @@ static int kvm_get_msrs(X86CPU *cpu)
if (has_msr_hv_runtime) {
msrs[n++].index = HV_X64_MSR_VP_RUNTIME;
}
+ if (cpu->hyperv_synic) {
+ uint32_t msr;
+
+ msrs[n++].index = HV_X64_MSR_SCONTROL;
+ msrs[n++].index = HV_X64_MSR_SVERSION;
+ msrs[n++].index = HV_X64_MSR_SIEFP;
+ msrs[n++].index = HV_X64_MSR_SIMP;
+ for (msr = HV_X64_MSR_SINT0; msr <= HV_X64_MSR_SINT15; msr++) {
+ msrs[n++].index = msr;
+ }
+ }
+ if (has_msr_hv_stimer) {
+ uint32_t msr;
+
+ for (msr = HV_X64_MSR_STIMER0_CONFIG; msr <= HV_X64_MSR_STIMER3_COUNT;
+ msr++) {
+ msrs[n++].index = msr;
+ }
+ }
if (has_msr_mtrr) {
msrs[n++].index = MSR_MTRRdefType;
msrs[n++].index = MSR_MTRRfix64K_00000;
@@ -2041,6 +2132,35 @@ static int kvm_get_msrs(X86CPU *cpu)
case HV_X64_MSR_VP_RUNTIME:
env->msr_hv_runtime = msrs[i].data;
break;
+ case HV_X64_MSR_SCONTROL:
+ env->msr_hv_synic_control = msrs[i].data;
+ break;
+ case HV_X64_MSR_SVERSION:
+ env->msr_hv_synic_version = msrs[i].data;
+ break;
+ case HV_X64_MSR_SIEFP:
+ env->msr_hv_synic_evt_page = msrs[i].data;
+ break;
+ case HV_X64_MSR_SIMP:
+ env->msr_hv_synic_msg_page = msrs[i].data;
+ break;
+ case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
+ env->msr_hv_synic_sint[index - HV_X64_MSR_SINT0] = msrs[i].data;
+ break;
+ case HV_X64_MSR_STIMER0_CONFIG:
+ case HV_X64_MSR_STIMER1_CONFIG:
+ case HV_X64_MSR_STIMER2_CONFIG:
+ case HV_X64_MSR_STIMER3_CONFIG:
+ env->msr_hv_stimer_config[(index - HV_X64_MSR_STIMER0_CONFIG)/2] =
+ msrs[i].data;
+ break;
+ case HV_X64_MSR_STIMER0_COUNT:
+ case HV_X64_MSR_STIMER1_COUNT:
+ case HV_X64_MSR_STIMER2_COUNT:
+ case HV_X64_MSR_STIMER3_COUNT:
+ env->msr_hv_stimer_count[(index - HV_X64_MSR_STIMER0_COUNT)/2] =
+ msrs[i].data;
+ break;
case MSR_MTRRdefType:
env->mtrr_deftype = msrs[i].data;
break;
@@ -2482,7 +2602,7 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
}
}
- if (!kvm_irqchip_in_kernel()) {
+ if (!kvm_pic_in_kernel()) {
qemu_mutex_lock_iothread();
}
@@ -2500,7 +2620,7 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
}
}
- if (!kvm_irqchip_in_kernel()) {
+ if (!kvm_pic_in_kernel()) {
/* Try to inject an interrupt if the guest can accept it */
if (run->ready_for_interrupt_injection &&
(cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
@@ -2899,6 +3019,13 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
ret = kvm_handle_debug(cpu, &run->debug.arch);
qemu_mutex_unlock_iothread();
break;
+ case KVM_EXIT_HYPERV:
+ ret = kvm_hv_handle_exit(cpu, &run->hyperv);
+ break;
+ case KVM_EXIT_IOAPIC_EOI:
+ ioapic_eoi_broadcast(run->eoi.vector);
+ ret = 0;
+ break;
default:
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
ret = -1;
@@ -2933,6 +3060,39 @@ void kvm_arch_init_irq_routing(KVMState *s)
*/
kvm_msi_via_irqfd_allowed = true;
kvm_gsi_routing_allowed = true;
+
+ if (kvm_irqchip_is_split()) {
+ int i;
+
+ /* If the ioapic is in QEMU and the lapics are in KVM, reserve
+ MSI routes for signaling interrupts to the local apics. */
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ struct MSIMessage msg = { 0x0, 0x0 };
+ if (kvm_irqchip_add_msi_route(s, msg, NULL) < 0) {
+ error_report("Could not enable split IRQ mode.");
+ exit(1);
+ }
+ }
+ }
+}
+
+int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
+{
+ int ret;
+ if (machine_kernel_irqchip_split(ms)) {
+ ret = kvm_vm_enable_cap(s, KVM_CAP_SPLIT_IRQCHIP, 0, 24);
+ if (ret) {
+ error_report("Could not enable split irqchip mode: %s\n",
+ strerror(-ret));
+ exit(1);
+ } else {
+ DPRINTF("Enabled KVM_CAP_SPLIT_IRQCHIP\n");
+ kvm_split_irqchip = true;
+ return 1;
+ }
+ } else {
+ return 0;
+ }
}
/* Classic KVM device assignment interface. Will remain x86 only. */
diff --git a/target-i386/kvm_i386.h b/target-i386/kvm_i386.h
index c1b312ba2a..42b00af1b1 100644
--- a/target-i386/kvm_i386.h
+++ b/target-i386/kvm_i386.h
@@ -13,6 +13,8 @@
#include "sysemu/kvm.h"
+#define kvm_apic_in_kernel() (kvm_irqchip_in_kernel())
+
bool kvm_allows_irq0_override(void);
bool kvm_has_smm(void);
void kvm_synchronize_all_tsc(void);
diff --git a/target-i386/machine.c b/target-i386/machine.c
index a18e16e0de..6126d96d7f 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -710,6 +710,70 @@ static const VMStateDescription vmstate_msr_hyperv_runtime = {
}
};
+static bool hyperv_synic_enable_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+ int i;
+
+ if (env->msr_hv_synic_control != 0 ||
+ env->msr_hv_synic_evt_page != 0 ||
+ env->msr_hv_synic_msg_page != 0) {
+ return true;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(env->msr_hv_synic_sint); i++) {
+ if (env->msr_hv_synic_sint[i] != 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static const VMStateDescription vmstate_msr_hyperv_synic = {
+ .name = "cpu/msr_hyperv_synic",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = hyperv_synic_enable_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(env.msr_hv_synic_control, X86CPU),
+ VMSTATE_UINT64(env.msr_hv_synic_evt_page, X86CPU),
+ VMSTATE_UINT64(env.msr_hv_synic_msg_page, X86CPU),
+ VMSTATE_UINT64_ARRAY(env.msr_hv_synic_sint, X86CPU,
+ HV_SYNIC_SINT_COUNT),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static bool hyperv_stimer_enable_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(env->msr_hv_stimer_config); i++) {
+ if (env->msr_hv_stimer_config[i] || env->msr_hv_stimer_count[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static const VMStateDescription vmstate_msr_hyperv_stimer = {
+ .name = "cpu/msr_hyperv_stimer",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = hyperv_stimer_enable_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_config,
+ X86CPU, HV_SYNIC_STIMER_COUNT),
+ VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_count,
+ X86CPU, HV_SYNIC_STIMER_COUNT),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static bool avx512_needed(void *opaque)
{
X86CPU *cpu = opaque;
@@ -893,6 +957,8 @@ VMStateDescription vmstate_x86_cpu = {
&vmstate_msr_hyperv_time,
&vmstate_msr_hyperv_crash,
&vmstate_msr_hyperv_runtime,
+ &vmstate_msr_hyperv_synic,
+ &vmstate_msr_hyperv_stimer,
&vmstate_avx512,
&vmstate_xss,
NULL
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index 8257b0e0f2..a482e474bc 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -128,7 +128,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
switch (cs->exception_index) {
case EXCP_HW_EXCP:
if (!(env->pvr.regs[0] & PVR0_USE_EXC_MASK)) {
- qemu_log("Exception raised on system without exceptions!\n");
+ qemu_log_mask(LOG_GUEST_ERROR, "Exception raised on system without exceptions!\n");
return;
}
diff --git a/target-microblaze/mmu.c b/target-microblaze/mmu.c
index 2ef1dc21a2..ee95a0457c 100644
--- a/target-microblaze/mmu.c
+++ b/target-microblaze/mmu.c
@@ -60,7 +60,7 @@ static void mmu_change_pid(CPUMBState *env, unsigned int newpid)
uint32_t t;
if (newpid & ~0xff)
- qemu_log("Illegal rpid=%x\n", newpid);
+ qemu_log_mask(LOG_GUEST_ERROR, "Illegal rpid=%x\n", newpid);
for (i = 0; i < ARRAY_SIZE(mmu->rams[RAM_TAG]); i++) {
/* Lookup and decode. */
@@ -121,7 +121,7 @@ unsigned int mmu_translate(struct microblaze_mmu *mmu,
t0 &= 0x3;
if (tlb_zsel > mmu->c_mmu_zones) {
- qemu_log("tlb zone select out of range! %d\n", tlb_zsel);
+ qemu_log_mask(LOG_GUEST_ERROR, "tlb zone select out of range! %d\n", tlb_zsel);
t0 = 1; /* Ignore. */
}
@@ -183,7 +183,7 @@ uint32_t mmu_read(CPUMBState *env, uint32_t rn)
uint32_t r;
if (env->mmu.c_mmu < 2 || !env->mmu.c_mmu_tlb_access) {
- qemu_log("MMU access on MMU-less system\n");
+ qemu_log_mask(LOG_GUEST_ERROR, "MMU access on MMU-less system\n");
return 0;
}
@@ -192,7 +192,7 @@ uint32_t mmu_read(CPUMBState *env, uint32_t rn)
case MMU_R_TLBLO:
case MMU_R_TLBHI:
if (!(env->mmu.c_mmu_tlb_access & 1)) {
- qemu_log("Invalid access to MMU reg %d\n", rn);
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid access to MMU reg %d\n", rn);
return 0;
}
@@ -204,7 +204,7 @@ uint32_t mmu_read(CPUMBState *env, uint32_t rn)
case MMU_R_PID:
case MMU_R_ZPR:
if (!(env->mmu.c_mmu_tlb_access & 1)) {
- qemu_log("Invalid access to MMU reg %d\n", rn);
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid access to MMU reg %d\n", rn);
return 0;
}
r = env->mmu.regs[rn];
@@ -224,7 +224,7 @@ void mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
D(qemu_log("%s rn=%d=%x old=%x\n", __func__, rn, v, env->mmu.regs[rn]));
if (env->mmu.c_mmu < 2 || !env->mmu.c_mmu_tlb_access) {
- qemu_log("MMU access on MMU-less system\n");
+ qemu_log_mask(LOG_GUEST_ERROR, "MMU access on MMU-less system\n");
return;
}
@@ -235,7 +235,7 @@ void mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
i = env->mmu.regs[MMU_R_TLBX] & 0xff;
if (rn == MMU_R_TLBHI) {
if (i < 3 && !(v & TLB_VALID) && qemu_loglevel_mask(~0))
- qemu_log("invalidating index %x at pc=%x\n",
+ qemu_log_mask(LOG_GUEST_ERROR, "invalidating index %x at pc=%x\n",
i, env->sregs[SR_PC]);
env->mmu.tids[i] = env->mmu.regs[MMU_R_PID] & 0xff;
mmu_flush_idx(env, i);
@@ -246,7 +246,7 @@ void mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
break;
case MMU_R_ZPR:
if (env->mmu.c_mmu_tlb_access <= 1) {
- qemu_log("Invalid access to MMU reg %d\n", rn);
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid access to MMU reg %d\n", rn);
return;
}
@@ -259,7 +259,7 @@ void mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
break;
case MMU_R_PID:
if (env->mmu.c_mmu_tlb_access <= 1) {
- qemu_log("Invalid access to MMU reg %d\n", rn);
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid access to MMU reg %d\n", rn);
return;
}
@@ -274,7 +274,7 @@ void mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
int hit;
if (env->mmu.c_mmu_tlb_access <= 1) {
- qemu_log("Invalid access to MMU reg %d\n", rn);
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid access to MMU reg %d\n", rn);
return;
}
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index d32434770c..56374621c2 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -55,7 +55,7 @@ void helper_put(uint32_t id, uint32_t ctrl, uint32_t data)
int nonblock = ctrl & STREAM_NONBLOCK;
int exception = ctrl & STREAM_EXCEPTION;
- qemu_log("Unhandled stream put to stream-id=%d data=%x %s%s%s%s%s\n",
+ qemu_log_mask(LOG_UNIMP, "Unhandled stream put to stream-id=%d data=%x %s%s%s%s%s\n",
id, data,
test ? "t" : "",
nonblock ? "n" : "",
@@ -72,7 +72,7 @@ uint32_t helper_get(uint32_t id, uint32_t ctrl)
int nonblock = ctrl & STREAM_NONBLOCK;
int exception = ctrl & STREAM_EXCEPTION;
- qemu_log("Unhandled stream get from stream-id=%d %s%s%s%s%s\n",
+ qemu_log_mask(LOG_UNIMP, "Unhandled stream get from stream-id=%d %s%s%s%s%s\n",
id,
test ? "t" : "",
nonblock ? "n" : "",
@@ -465,8 +465,8 @@ void helper_memalign(CPUMBState *env, uint32_t addr, uint32_t dr, uint32_t wr,
void helper_stackprot(CPUMBState *env, uint32_t addr)
{
if (addr < env->slr || addr > env->shr) {
- qemu_log("Stack protector violation at %x %x %x\n",
- addr, env->slr, env->shr);
+ qemu_log_mask(CPU_LOG_INT, "Stack protector violation at %x %x %x\n",
+ addr, env->slr, env->shr);
env->sregs[SR_EAR] = addr;
env->sregs[SR_ESR] = ESR_EC_STACKPROT;
helper_raise_exception(env, EXCP_HW_EXCP);
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 154b9d6836..9e520114a4 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1516,7 +1516,7 @@ static void dec_null(DisasContext *dc)
t_gen_raise_exception(dc, EXCP_HW_EXCP);
return;
}
- qemu_log ("unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
+ qemu_log_mask(LOG_GUEST_ERROR, "unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
dc->abort_at_next_insn = 1;
}
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 4250106b34..dbc070c2a7 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -23,6 +23,7 @@
#include "helper_regs.h"
//#define DEBUG_OP
+//#define DEBUG_SOFTWARE_TLB
//#define DEBUG_EXCEPTIONS
#ifdef DEBUG_EXCEPTIONS
@@ -131,12 +132,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
/* Machine check exception is not enabled.
* Enter checkstop state.
*/
- if (qemu_log_enabled()) {
+ fprintf(stderr, "Machine check while not allowed. "
+ "Entering checkstop state\n");
+ if (qemu_log_separate()) {
qemu_log("Machine check while not allowed. "
"Entering checkstop state\n");
- } else {
- fprintf(stderr, "Machine check while not allowed. "
- "Entering checkstop state\n");
}
cs->halted = 1;
cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index dfee358d6a..a00ae3c94a 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -24,17 +24,10 @@
#include "kvm_ppc.h"
#include "mmu-hash32.h"
-//#define DEBUG_MMU
//#define DEBUG_BAT
-#ifdef DEBUG_MMU
-# define LOG_MMU_STATE(cpu) log_cpu_state((cpu), 0)
-#else
-# define LOG_MMU_STATE(cpu) do { } while (0)
-#endif
-
#ifdef DEBUG_BATS
-# define LOG_BATS(...) qemu_log(__VA_ARGS__)
+# define LOG_BATS(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
#else
# define LOG_BATS(...) do { } while (0)
#endif
@@ -281,9 +274,8 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
}
return 1;
default:
- qemu_log("ERROR: instruction should not need "
+ cpu_abort(cs, "ERROR: instruction should not need "
"address translation\n");
- abort();
}
if ((rwx == 1 || key != 1) && (rwx == 0 || key != 0)) {
*raddr = eaddr;
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 7df6edebf2..34e20fa3a9 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -23,17 +23,10 @@
#include "kvm_ppc.h"
#include "mmu-hash64.h"
-//#define DEBUG_MMU
//#define DEBUG_SLB
-#ifdef DEBUG_MMU
-# define LOG_MMU_STATE(cpu) log_cpu_state((cpu), 0)
-#else
-# define LOG_MMU_STATE(cpu) do { } while (0)
-#endif
-
#ifdef DEBUG_SLB
-# define LOG_SLB(...) qemu_log(__VA_ARGS__)
+# define LOG_SLB(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
#else
# define LOG_SLB(...) do { } while (0)
#endif
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 30298d8d4a..52176916ba 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -28,23 +28,22 @@
//#define DEBUG_BATS
//#define DEBUG_SOFTWARE_TLB
//#define DUMP_PAGE_TABLES
-//#define DEBUG_SOFTWARE_TLB
//#define FLUSH_ALL_TLBS
#ifdef DEBUG_MMU
-# define LOG_MMU_STATE(cpu) log_cpu_state((cpu), 0)
+# define LOG_MMU_STATE(cpu) log_cpu_state_mask(CPU_LOG_MMU, (cpu), 0)
#else
# define LOG_MMU_STATE(cpu) do { } while (0)
#endif
#ifdef DEBUG_SOFTWARE_TLB
-# define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
+# define LOG_SWTLB(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
#else
# define LOG_SWTLB(...) do { } while (0)
#endif
#ifdef DEBUG_BATS
-# define LOG_BATS(...) qemu_log(__VA_ARGS__)
+# define LOG_BATS(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
#else
# define LOG_BATS(...) do { } while (0)
#endif
@@ -162,7 +161,7 @@ static inline int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
if (ctx->raddr != (hwaddr)-1ULL) {
/* all matches should have equal RPN, WIMG & PP */
if ((ctx->raddr & mmask) != (pte1 & mmask)) {
- qemu_log("Bad RPN/WIMG/PP\n");
+ qemu_log_mask(CPU_LOG_MMU, "Bad RPN/WIMG/PP\n");
return -3;
}
}
@@ -508,7 +507,7 @@ static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
/* Software TLB search */
ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
#if defined(DUMP_PAGE_TABLES)
- if (qemu_log_enabled()) {
+ if (qemu_log_mask(CPU_LOG_MMU)) {
hwaddr curaddr;
uint32_t a0, a1, a2, a3;
@@ -575,8 +574,8 @@ static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
/* eciwx or ecowx */
return -4;
default:
- qemu_log("ERROR: instruction should not need "
- "address translation\n");
+ qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need "
+ "address translation\n");
return -4;
}
if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
diff --git a/target-ppc/timebase_helper.c b/target-ppc/timebase_helper.c
index 865dcbed22..cafa283899 100644
--- a/target-ppc/timebase_helper.c
+++ b/target-ppc/timebase_helper.c
@@ -130,13 +130,14 @@ target_ulong helper_load_dcr(CPUPPCState *env, target_ulong dcrn)
uint32_t val = 0;
if (unlikely(env->dcr_env == NULL)) {
- qemu_log("No DCR environment\n");
+ qemu_log_mask(LOG_GUEST_ERROR, "No DCR environment\n");
helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
POWERPC_EXCP_INVAL |
POWERPC_EXCP_INVAL_INVAL);
} else if (unlikely(ppc_dcr_read(env->dcr_env,
(uint32_t)dcrn, &val) != 0)) {
- qemu_log("DCR read error %d %03x\n", (uint32_t)dcrn, (uint32_t)dcrn);
+ qemu_log_mask(LOG_GUEST_ERROR, "DCR read error %d %03x\n",
+ (uint32_t)dcrn, (uint32_t)dcrn);
helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
}
@@ -146,13 +147,14 @@ target_ulong helper_load_dcr(CPUPPCState *env, target_ulong dcrn)
void helper_store_dcr(CPUPPCState *env, target_ulong dcrn, target_ulong val)
{
if (unlikely(env->dcr_env == NULL)) {
- qemu_log("No DCR environment\n");
+ qemu_log_mask(LOG_GUEST_ERROR, "No DCR environment\n");
helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
POWERPC_EXCP_INVAL |
POWERPC_EXCP_INVAL_INVAL);
} else if (unlikely(ppc_dcr_write(env->dcr_env, (uint32_t)dcrn,
(uint32_t)val) != 0)) {
- qemu_log("DCR write error %d %03x\n", (uint32_t)dcrn, (uint32_t)dcrn);
+ qemu_log_mask(LOG_GUEST_ERROR, "DCR write error %d %03x\n",
+ (uint32_t)dcrn, (uint32_t)dcrn);
helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
}
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 41a7258486..4be7eaaf9b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -4285,19 +4285,23 @@ static inline void gen_op_mfspr(DisasContext *ctx)
* allowing userland application to read the PVR
*/
if (sprn != SPR_PVR) {
- qemu_log("Trying to read privileged spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- printf("Trying to read privileged spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ fprintf(stderr, "Trying to read privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ if (qemu_log_separate()) {
+ qemu_log("Trying to read privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ }
}
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
} else {
/* Not defined */
- qemu_log("Trying to read invalid spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- printf("Trying to read invalid spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ if (qemu_log_separate()) {
+ qemu_log("Trying to read invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ }
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
}
}
@@ -4431,18 +4435,22 @@ static void gen_mtspr(DisasContext *ctx)
(*write_cb)(ctx, sprn, rS(ctx->opcode));
} else {
/* Privilege exception */
- qemu_log("Trying to write privileged spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- printf("Trying to write privileged spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ fprintf(stderr, "Trying to write privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ if (qemu_log_separate()) {
+ qemu_log("Trying to write privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ }
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
} else {
/* Not defined */
- qemu_log("Trying to write invalid spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- printf("Trying to write invalid spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ if (qemu_log_separate()) {
+ qemu_log("Trying to write invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ }
+ fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
}
}
@@ -11522,12 +11530,10 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
}
/* Is opcode *REALLY* valid ? */
if (unlikely(handler->handler == &gen_invalid)) {
- if (qemu_log_enabled()) {
- qemu_log("invalid/unsupported opcode: "
- "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
- opc1(ctx.opcode), opc2(ctx.opcode),
- opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
- }
+ qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
+ "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
+ opc1(ctx.opcode), opc2(ctx.opcode),
+ opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
} else {
uint32_t inval;
@@ -11538,13 +11544,11 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
}
if (unlikely((ctx.opcode & inval) != 0)) {
- if (qemu_log_enabled()) {
- qemu_log("invalid bits: %08x for opcode: "
- "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
- ctx.opcode & inval, opc1(ctx.opcode),
- opc2(ctx.opcode), opc3(ctx.opcode),
- ctx.opcode, ctx.nip - 4);
- }
+ qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
+ "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
+ ctx.opcode & inval, opc1(ctx.opcode),
+ opc2(ctx.opcode), opc3(ctx.opcode),
+ ctx.opcode, ctx.nip - 4);
gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
break;
}
diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
index bfce3f1e60..c4ee00268f 100644
--- a/target-s390x/cc_helper.c
+++ b/target-s390x/cc_helper.c
@@ -560,7 +560,7 @@ void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
env->psw.mask |= PSW_ASC_HOME;
break;
default:
- qemu_log("unknown sacf mode: %" PRIx64 "\n", a1);
+ HELPER_LOG("unknown sacf mode: %" PRIx64 "\n", a1);
program_interrupt(env, PGM_SPECIFICATION, 2);
break;
}
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index d88700695e..aa58f39db4 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -33,7 +33,7 @@
#ifdef DEBUG_S390_STDOUT
#define DPRINTF(fmt, ...) \
do { fprintf(stderr, fmt, ## __VA_ARGS__); \
- qemu_log(fmt, ##__VA_ARGS__); } while (0)
+ if (qemu_log_separate()) qemu_log(fmt, ##__VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) \
do { qemu_log(fmt, ## __VA_ARGS__); } while (0)
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index b601a33606..dab02d3c2b 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -299,7 +299,7 @@ void HELPER(spx)(CPUS390XState *env, uint64_t a1)
uint32_t prefix = a1 & 0x7fffe000;
env->psa = prefix;
- qemu_log("prefix: %#x\n", prefix);
+ HELPER_LOG("prefix: %#x\n", prefix);
tlb_flush_page(cs, 0);
tlb_flush_page(cs, TARGET_PAGE_SIZE);
}
diff --git a/target-s390x/mmu_helper.c b/target-s390x/mmu_helper.c
index 058a37013b..f4e1872b42 100644
--- a/target-s390x/mmu_helper.c
+++ b/target-s390x/mmu_helper.c
@@ -30,7 +30,7 @@
#ifdef DEBUG_S390_STDOUT
#define DPRINTF(fmt, ...) \
do { fprintf(stderr, fmt, ## __VA_ARGS__); \
- qemu_log(fmt, ##__VA_ARGS__); } while (0)
+ if (qemu_log_separate()) qemu_log(fmt, ##__VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) \
do { qemu_log(fmt, ## __VA_ARGS__); } while (0)
diff --git a/target-tricore/helper.c b/target-tricore/helper.c
index 1808b281f5..1b70429f3a 100644
--- a/target-tricore/helper.c
+++ b/target-tricore/helper.c
@@ -65,8 +65,8 @@ int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong address,
access_type = ACCESS_INT;
ret = get_physical_address(env, &physical, &prot,
address, rw, access_type);
- qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx
- " prot %d\n", __func__, address, ret, physical, prot);
+ qemu_log_mask(CPU_LOG_MMU, "%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx
+ " prot %d\n", __func__, address, ret, physical, prot);
if (ret == TLBRET_MATCH) {
tlb_set_page(cs, address & TARGET_PAGE_MASK,
diff --git a/target-xtensa/gdbstub.c b/target-xtensa/gdbstub.c
index bc2e1b55f6..dcf05ad88c 100644
--- a/target-xtensa/gdbstub.c
+++ b/target-xtensa/gdbstub.c
@@ -63,8 +63,8 @@ int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]);
default:
- qemu_log("%s from reg %d of unsupported type %d\n",
- __func__, n, reg->type);
+ qemu_log_mask(LOG_UNIMP, "%s from reg %d of unsupported type %d\n",
+ __func__, n, reg->type);
return 0;
}
}
@@ -117,8 +117,8 @@ int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
break;
default:
- qemu_log("%s to reg %d of unsupported type %d\n",
- __func__, n, reg->type);
+ qemu_log_mask(LOG_UNIMP, "%s to reg %d of unsupported type %d\n",
+ __func__, n, reg->type);
return 0;
}
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index 2c3447ba6b..cf25bf8fbf 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -254,8 +254,8 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
env->config->exception_vector[cs->exception_index]);
env->exception_taken = 1;
} else {
- qemu_log("%s(pc = %08x) bad exception_index: %d\n",
- __func__, env->pc, cs->exception_index);
+ qemu_log_mask(CPU_LOG_INT, "%s(pc = %08x) bad exception_index: %d\n",
+ __func__, env->pc, cs->exception_index);
}
break;
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 718e54e7b5..02100af442 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -245,8 +245,8 @@ void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm)
{
int callinc = (env->sregs[PS] & PS_CALLINC) >> PS_CALLINC_SHIFT;
if (s > 3 || ((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) != 0) {
- qemu_log("Illegal entry instruction(pc = %08x), PS = %08x\n",
- pc, env->sregs[PS]);
+ qemu_log_mask(LOG_GUEST_ERROR, "Illegal entry instruction(pc = %08x), PS = %08x\n",
+ pc, env->sregs[PS]);
HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE);
} else {
uint32_t windowstart = xtensa_replicate_windowstart(env) >>
@@ -307,9 +307,9 @@ uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc)
if (n == 0 || (m != 0 && m != n) ||
((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) != 0) {
- qemu_log("Illegal retw instruction(pc = %08x), "
- "PS = %08x, m = %d, n = %d\n",
- pc, env->sregs[PS], m, n);
+ qemu_log_mask(LOG_GUEST_ERROR, "Illegal retw instruction(pc = %08x), "
+ "PS = %08x, m = %d, n = %d\n",
+ pc, env->sregs[PS], m, n);
HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE);
} else {
int owb = windowbase;
@@ -743,8 +743,8 @@ void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
xtensa_tlb_set_entry_mmu(env, entry, dtlb, wi, ei, vpn, pte);
tlb_flush_page(cs, entry->vaddr);
} else {
- qemu_log("%s %d, %d, %d trying to set immutable entry\n",
- __func__, dtlb, wi, ei);
+ qemu_log_mask(LOG_GUEST_ERROR, "%s %d, %d, %d trying to set immutable entry\n",
+ __func__, dtlb, wi, ei);
}
} else {
tlb_flush_page(cs, entry->vaddr);
@@ -806,15 +806,15 @@ static void set_dbreak(CPUXtensaState *env, unsigned i, uint32_t dbreaka,
}
/* contiguous mask after inversion is one less than some power of 2 */
if ((~mask + 1) & ~mask) {
- qemu_log("DBREAKC mask is not contiguous: 0x%08x\n", dbreakc);
+ qemu_log_mask(LOG_GUEST_ERROR, "DBREAKC mask is not contiguous: 0x%08x\n", dbreakc);
/* cut mask after the first zero bit */
mask = 0xffffffff << (32 - clo32(mask));
}
if (cpu_watchpoint_insert(cs, dbreaka & mask, ~mask + 1,
flags, &env->cpu_watchpoint[i])) {
env->cpu_watchpoint[i] = NULL;
- qemu_log("Failed to set data breakpoint at 0x%08x/%d\n",
- dbreaka & mask, ~mask + 1);
+ qemu_log_mask(LOG_GUEST_ERROR, "Failed to set data breakpoint at 0x%08x/%d\n",
+ dbreaka & mask, ~mask + 1);
}
}
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 06b0163412..fbcec945a1 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -501,9 +501,9 @@ static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
{
if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) {
if (sregnames[sr].name) {
- qemu_log("SR %s is not configured\n", sregnames[sr].name);
+ qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not configured\n", sregnames[sr].name);
} else {
- qemu_log("SR %d is not implemented\n", sr);
+ qemu_log_mask(LOG_UNIMP, "SR %d is not implemented\n", sr);
}
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
return false;
@@ -514,8 +514,8 @@ static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
[SR_X] = "xsr",
};
assert(access < ARRAY_SIZE(access_text) && access_text[access]);
- qemu_log("SR %s is not available for %s\n", sregnames[sr].name,
- access_text[access]);
+ qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not available for %s\n", sregnames[sr].name,
+ access_text[access]);
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
return false;
}
@@ -875,18 +875,18 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
{
#define HAS_OPTION_BITS(opt) do { \
if (!option_bits_enabled(dc, opt)) { \
- qemu_log("Option is not enabled %s:%d\n", \
- __FILE__, __LINE__); \
+ qemu_log_mask(LOG_GUEST_ERROR, "Option is not enabled %s:%d\n", \
+ __FILE__, __LINE__); \
goto invalid_opcode; \
} \
} while (0)
#define HAS_OPTION(opt) HAS_OPTION_BITS(XTENSA_OPTION_BIT(opt))
-#define TBD() qemu_log("TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
+#define TBD() qemu_log_mask(LOG_UNIMP, "TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
#define RESERVED() do { \
- qemu_log("RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
- dc->pc, b0, b1, b2, __FILE__, __LINE__); \
+ qemu_log_mask(LOG_GUEST_ERROR, "RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
+ dc->pc, b0, b1, b2, __FILE__, __LINE__); \
goto invalid_opcode; \
} while (0)
@@ -1186,7 +1186,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
gen_jump(dc, cpu_SR[EPC1 + RRR_S - 1]);
}
} else {
- qemu_log("RFI %d is illegal\n", RRR_S);
+ qemu_log_mask(LOG_GUEST_ERROR, "RFI %d is illegal\n", RRR_S);
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
}
break;
@@ -1222,7 +1222,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
gen_helper_simcall(cpu_env);
}
} else {
- qemu_log("SIMCALL but semihosting is disabled\n");
+ qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
}
break;
@@ -1865,7 +1865,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
if (uregnames[st].name) {
tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
} else {
- qemu_log("RUR %d not implemented, ", st);
+ qemu_log_mask(LOG_UNIMP, "RUR %d not implemented, ", st);
TBD();
}
}
@@ -1876,7 +1876,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
if (uregnames[RSR_SR].name) {
gen_wur(RSR_SR, cpu_R[RRR_T]);
} else {
- qemu_log("WUR %d not implemented, ", RSR_SR);
+ qemu_log_mask(LOG_UNIMP, "WUR %d not implemented, ", RSR_SR);
TBD();
}
}
@@ -3006,7 +3006,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
return;
invalid_opcode:
- qemu_log("INVALID(pc = %08x)\n", dc->pc);
+ qemu_log_mask(LOG_GUEST_ERROR, "INVALID(pc = %08x)\n", dc->pc);
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
#undef HAS_OPTION
}
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
index 16e9d8c7b8..384d9c2ebe 100644
--- a/target-xtensa/xtensa-semi.c
+++ b/target-xtensa/xtensa-semi.c
@@ -313,7 +313,7 @@ void HELPER(simcall)(CPUXtensaState *env)
break;
default:
- qemu_log("%s(%d): not implemented\n", __func__, regs[2]);
+ qemu_log_mask(LOG_GUEST_ERROR, "%s(%d): not implemented\n", __func__, regs[2]);
regs[2] = -1;
regs[3] = TARGET_ENOSYS;
break;
diff --git a/trace-events b/trace-events
index 55f5b9ed2c..fa504cf494 100644
--- a/trace-events
+++ b/trace-events
@@ -1758,6 +1758,9 @@ cpu_unhalt(int cpu_index) "unhalting cpu %d"
# hw/arm/virt-acpi-build.c
virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
+# hw/alpha/pci.c
+alpha_pci_iack_write(void) ""
+
# audio/alsaaudio.c
alsa_revents(int revents) "revents = %d"
alsa_pollout(int i, int fd) "i = %d fd = %d"
@@ -1794,3 +1797,14 @@ qcrypto_tls_session_new(void *session, void *creds, const char *hostname, const
# net/vhost-user.c
vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
+
+# linux-user/signal.c
+user_setup_frame(void *env, uint64_t frame_addr) "env=%p frame_addr="PRIx64""
+user_setup_rt_frame(void *env, uint64_t frame_addr) "env=%p frame_addr="PRIx64""
+user_do_rt_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr="PRIx64""
+user_do_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr="PRIx64""
+user_force_sig(void *env, int target_sig, int host_sig) "env=%p signal %d (host %d)"
+user_handle_signal(void *env, int target_sig) "env=%p signal %d"
+user_host_signal(void *env, int host_sig, int target_sig) "env=%p signal %d (target %d("
+user_queue_signal(void *env, int target_sig) "env=%p signal %d"
+user_s390x_restore_sigregs(void *env, uint64_t sc_psw_addr, uint64_t env_psw_addr) "env=%p frame psw.addr "PRIx64 " current psw.addr "PRIx64""