unicorn/qemu
Alex Williamson fe66c2e088
memory: Don't use memcpy for ram_device regions
With a vfio assigned device we lay down a base MemoryRegion registered
as an IO region, giving us read & write accessors. If the region
supports mmap, we lay down a higher priority sub-region MemoryRegion
on top of the base layer initialized as a RAM device pointer to the
mmap. Finally, if we have any quirks for the device (ie. address
ranges that need additional virtualization support), we put another IO
sub-region on top of the mmap MemoryRegion. When this is flattened,
we now potentially have sub-page mmap MemoryRegions exposed which
cannot be directly mapped through KVM.

This is as expected, but a subtle detail of this is that we end up
with two different access mechanisms through QEMU. If we disable the
mmap MemoryRegion, we make use of the IO MemoryRegion and service
accesses using pread and pwrite to the vfio device file descriptor.
If the mmap MemoryRegion is enabled and results in one of these
sub-page gaps, QEMU handles the access as RAM, using memcpy to the
mmap. Using either pread/pwrite or the mmap directly should be
correct, but using memcpy causes us problems. I expect that not only
does memcpy not necessarily honor the original width and alignment in
performing a copy, but it potentially also uses processor instructions
not intended for MMIO spaces. It turns out that this has been a
problem for Realtek NIC assignment, which has such a quirk that
creates a sub-page mmap MemoryRegion access.

To resolve this, we disable memory_access_is_direct() for ram_device
regions since QEMU assumes that it can use memcpy for those regions.
Instead we access through MemoryRegionOps, which replaces the memcpy
with simple de-references of standard sizes to the host memory.

With this patch we attempt to provide unrestricted access to the RAM
device, allowing byte through qword access as well as unaligned
access. The assumption here is that accesses initiated by the VM are
driven by a device specific driver, which knows the device
capabilities. If unaligned accesses are not supported by the device,
we don't want them to work in a VM by performing multiple aligned
accesses to compose the unaligned access. A down-side of this
philosophy is that the xp command from the monitor attempts to use
the largest available access weidth, unaware of the underlying
device. Using memcpy had this same restriction, but at least now an
operator can dump individual registers, even if blocks of device
memory may result in access widths beyond the capabilities of a
given device (RTL NICs only support up to dword).

Backports commit 1b16ded6a512809f99c133a97f19026fe612b2de from qemu
2018-02-25 23:06:36 -05:00
..
crypto crypto: Clean up includes 2018-02-19 00:47:40 -05:00
default-configs arm64eb: add support for ARM64 big endian. 2017-04-24 23:30:01 +08:00
docs docs: clarify memory region lifecycle 2018-02-12 15:11:21 -05:00
fpu softfloat: Fix warn about implicit conversion from int to int8_t 2018-02-25 22:54:39 -05:00
hw qdev: Fix object reference leak in case device.realize() fails 2018-02-25 21:00:26 -05:00
include memory: Don't use memcpy for ram_device regions 2018-02-25 23:06:36 -05:00
qapi qapi: change QmpInputVisitor to QSLIST 2018-02-25 20:02:09 -05:00
qobject util: move declarations out of qemu-common.h 2018-02-22 09:25:48 -05:00
qom qapi: Add new visit_complete() function 2018-02-25 01:20:03 -05:00
scripts qapi: Implement boxed types for commands/events 2018-02-25 20:22:03 -05:00
target-arm target-arm: Fix warn about implicit conversion 2018-02-25 22:44:43 -05:00
target-i386 tcg: Reorg TCGOp chaining 2018-02-25 21:44:50 -05:00
target-m68k tcg: Reorg TCGOp chaining 2018-02-25 21:44:50 -05:00
target-mips target-mips: Silence unused function warning 2018-02-25 21:47:22 -05:00
target-sparc tcg: Reorg TCGOp chaining 2018-02-25 21:44:50 -05:00
tcg tcg: Lower indirect registers in a separate pass 2018-02-25 22:32:28 -05:00
util util: Move qemu-log to utils 2018-02-25 22:17:44 -05:00
aarch64.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
aarch64eb.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
accel.c accel: make configure_accelerator return void 2018-02-24 00:31:28 -05:00
arm.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
armeb.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
CODING_STYLE import 2015-08-21 15:04:50 +08:00
configure configure: Enable -Werror for MinGW builds, too 2018-02-24 18:56:05 -05:00
COPYING import 2015-08-21 15:04:50 +08:00
COPYING.LIB import 2015-08-21 15:04:50 +08:00
cpu-exec-common.c cpu-exec: Rename cpu_resume_from_signal() to cpu_loop_exit_noexc() 2018-02-24 17:25:28 -05:00
cpu-exec.c tb hash: hash phys_pc, pc, and flags with xxhash 2018-02-24 18:00:14 -05:00
cpus.c cpu: move exec-all.h inclusion out of cpu.h 2018-02-24 02:39:08 -05:00
cputlb.c cputlb: Add address parameter to VICTIM_TLB_HIT 2018-02-25 03:03:36 -05:00
exec.c exec: avoid realloc in phys_map_node_reserve 2018-02-25 19:32:40 -05:00
gen_all_header.sh arm64eb: add support for ARM64 big endian. 2017-04-24 23:30:01 +08:00
glib_compat.c qapi: Fix memleak in string visitors on int lists 2018-02-25 00:20:34 -05:00
HACKING import 2015-08-21 15:04:50 +08:00
header_gen.py memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
ioport.c hw: remove pio_addr_t 2018-02-24 02:43:16 -05:00
LICENSE import 2015-08-21 15:04:50 +08:00
m68k.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
Makefile Makefile: Add a FORCE target 2018-02-24 17:03:51 -05:00
Makefile.objs util: Move qemu-log to utils 2018-02-25 22:17:44 -05:00
Makefile.target tcg: split tcg_op_defs to -common 2018-02-17 15:23:51 -05:00
memory.c memory: Don't use memcpy for ram_device regions 2018-02-25 23:06:36 -05:00
memory_mapping.c include/qemu/osdep.h: Don't include qapi/error.h 2018-02-21 23:08:18 -05:00
mips.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
mips64.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
mips64el.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
mipsel.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
powerpc.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
qapi-schema.json qapi: Lazy creation of array types 2018-02-19 18:55:35 -05:00
qemu-timer.c all: Clean up includes 2018-02-19 01:34:28 -05:00
rules.mak Makefile: add dependency on scripts/create_config 2018-02-24 17:05:03 -05:00
softmmu_template.h cputlb: Fix for self-modifying writes across page boundaries 2018-02-25 03:12:11 -05:00
sparc.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
sparc64.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00
tcg-runtime.c all: Clean up includes 2018-02-19 01:34:28 -05:00
translate-all.c translate-all: Fix user-mode self-modifying code in 2 page long TB 2018-02-25 03:14:22 -05:00
translate-all.h user-exec: Push resume-from-signal code out to handle_cpu_signal() 2018-02-24 17:21:06 -05:00
translate-common.c exec: Clean up includes 2018-02-19 00:49:55 -05:00
unicorn_common.h qom/cpu: Add MemoryRegion property 2018-02-18 21:54:50 -05:00
VERSION import 2015-08-21 15:04:50 +08:00
vl.c hw: explicitly include qemu/log.h 2018-02-24 02:00:45 -05:00
vl.h import 2015-08-21 15:04:50 +08:00
x86_64.h memory: Replace skip_dump flag with ram_device 2018-02-25 23:00:45 -05:00