Age | Commit message (Collapse) | Author |
|
When storing large contiguous ranges in phys_map, all values tend to
be the same pointers to a single MemoryRegionSection. Collapse them
by marking nodes with level > 0 as leaves. This reduces tree memory
usage dramatically.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
They have the same type, unify them.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Setting multiple pages at once requires backtracking to previous
nodes; easiest to achieve via recursion.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
By giving the function the value we want to set, we make it
more flexible for the next patch.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Instead of considering subpage on a per-page basis, split each section
into a subpage head, multipage body, and subpage tail, and register
each separately. This simplifies the registration functions.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
We'll change phys_page_find_alloc() soon, but phys_page_find()
doesn't need to bear the consequences.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
We no longer describe memory in terms of individual pages; use sections
throughout instead.
PhysPageDesc no longer used - remove.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
This way, if we have several changes in a single transaction, we flush just
once.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Identical except that the second branch knows its not modifying an existing
subpage.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
If the first subpage installed in a page is RAM, then we install it as
a full page, instead of a subpage. Fix by not special casing RAM.
The issue dates to commit db7b5426a4b4242, which introduced subpages.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Use an expanding vector to store nodes. Allocation is baroque to g_renew()
potentially invalidating pointers; this will be addressed later.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Instead of storing PhysPageDesc, store pointers to MemoryRegionSections.
The various offsets (phys_offset & ~TARGET_PAGE_MASK,
PHYS_OFFSET & TARGET_PAGE_MASK, region_offset) can all be synthesized
from the information in a MemoryRegionSection. Adjust phys_page_find()
to synthesize a PhysPageDesc.
The upshot is that phys_map now contains uniform values, so it's easier
to generate and compress.
The end result is somewhat clumsy but this will be improved as we we
propagate MemoryRegionSections throughout the code instead of transforming
them to PhysPageDesc.
The MemoryRegionSection pointers are stored as uint16_t offsets in an
array. This saves space (when we also compress node pointers) and is
more cache friendly.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
This lays the groundwork for storing leaf data in intermediate levels,
saving space.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
L1 and the lower levels in l1_phys_map are equivalent, except that L1 has
a different size, and is always allocated. Simplify the code by removing
L1. This leaves us with a tree composed solely of L2 tables, but that
problem can be renamed away later.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Instead of incrementally building the memory map, rebuild it every time.
This allows later simplification, since the code need not consider overlaying
a previous mapping. It is also RCU friendly.
With large memory guests this can get expensive, since the operation is
O(mem size), but this will be optimized later.
As a side effect subpage and L2 leaks are fixed here.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Current memory listeners are incremental; that is, they are expected to
maintain their own state, and receive callbacks for changes to that state.
This patch adds support for stateless listeners; these work by receiving
a ->begin() callback (which tells them that new state is coming), a
sequence of ->region_add() and ->region_nop() callbacks, and then a
->commit() callback which signifies the end of the new state. They should
ignore ->region_del() callbacks.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
The memory and I/O address spaces do different things, so split them into
two memory listeners.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Ignore any regions not belonging to a specified address space.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
This transforms memory.c into a library which can then be unit tested
easily, by feeding it inputs and listening to its outputs.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
It can be derived from the MemoryRegion itself (which is why it is not
used there).
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Clarify the comment about tlb_flush()'s flush_global parameter,
so it is clearer what it does and why it is OK that the implementation
currently ignores it.
Reviewed-by: Andreas F=C3=A4rber <afaerber@suse.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
|
The virtio config area in PIO space is a bit special. The initial
header is little endian but the rest (device specific) is guest
native endian.
The PIO accessors for PCI on machines that don't have native IO ports
assume that all PIO is little endian, which works fine for everything
except the above.
A complicated way to fix it would be to split the BAR into two memory
regions with different endianess settings, but this isn't practical
to do, besides, the PIO code doesn't honor region endianness anyway
(I have a patch for that too but it isn't necessary at this stage).
So I decided to go for the quick fix instead which consists of
reverting the swap in virtio-pci in selected places, hoping that when
we eventually do a "v2" of the virtio protocols, we sort that out once
and for all using a fixed endian setting for everything.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
[agraf: keep virtio in libhw and determine endianness through a
helper function in exec.c]
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
|
|
ARM still doesn't support 16GB buffers in 32-bit modes, replace the
16GB by 16MB in the comment.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
|
We no longer use any of the lower bits of a ram_addr, so we might as well
use them for the io table index. This increases the number of potential
I/O handlers by a factor of 8.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Unlike ->readonly, ->readable is not inherited from aliase, so we can simply
query the memory region.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Replace with a MemoryRegion flag.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Now that all mmio goes through MemoryRegions, we can convert
io_mem_opaque to be a MemoryRegion pointer, and remove the thunks
that convert from old-style CPU{Read,Write}MemoryFunc to MemoryRegionOps.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Still internally using ram_addr.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Convert the fixed-address IO_MEM_RAM, IO_MEM_ROM, IO_MEM_UNASSIGNED,
and IO_MEM_NOTDIRTY io handlers to MemoryRegions. These aren't real
regions, since they are never added to the memory hierarchy, but they
allow reuse of the dispatch functionality.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Its use of IO_MEM_ROM and friends will later cause #include loops; and it
is too large to merit inlining.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
The code sometimes uses range comparisons on io indexes (e.g.
index =< IO_MEM_ROM). Avoid these as they make moving to objects harder.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
cpu_register_physical_memory_log() does not update region_offset
if a page was previously registered for the same address. This
could cause mmio accesses going to the wrong place, by using the
old region_offset.
Signed-off-by: Avi Kivity <avi@redhat.com>
Acked-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Currently mmio access goes directly to the io_mem_{read,write} arrays.
In preparation for eliminating them, add indirection via a function.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Instead of returning a PhysPageDesc pointer, return a temporary.
This lets us move away from actually storing PhysPageDesc's, and
instead sythesising them when needed.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
Instead of doing device endianness compensation in cpu_register_io_memory(),
do it in the memory core.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
The getter is no longer used, so it is completely removed.
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
As a step in moving live migration from RAMBlocks to MemoryRegions,
store the MemoryRegion in a RAMBlock.
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Currently creating a memory region automatically registers it for
live migration. This differs from other state (which is enumerated
in a VMStateDescription structure) and ties the live migration code
into the memory core.
Decouple the two by introducing a separate API, vmstate_register_ram(),
for registering a RAM block for migration. Currently the same
implementation is reused, but later it can be moved into a separate list,
and registrations can be moved to VMStateDescription blocks.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
No longer used.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
No longer used.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Add an API that allows a client to observe changes in the global
memory map:
- region added (possibly with logging enabled)
- region removed (possibly with logging enabled)
- logging started on a region
- logging stopped on a region
- global logging started
- global logging removed
This API will eventually replace cpu_register_physical_memory_client().
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
This will help avoid accidental usage.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Currently xen_ram_alloc() relies on ram_addr, which is going away.
Give it something else to use as a cookie.
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
This fixes a common bug with initial region_offset value.
Usually, the pages are re-assigned afterwards, so the bug
has a very small effect on regular QEMU use flows.
Signed-off-by: Alex Rozenman <Alex_Rozenman@mentor.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
|
Commit 95c318f5e1f88d7e5bcc6deac17330fd4806a2d3 (Fix segfault in mmio
subpage handling code.) prevented a segfault by making all subpage
registrations over an existing memory page perform an unassigned access.
Symptoms were writes not taking effect and reads returning zero.
Very small page sizes are not currently supported either,
so subpage memory areas cannot fully be avoided.
Therefore change the previous fix to use a new IO_MEM_SUBPAGE_RAM
instead of IO_MEM_UNASSIGNED. Suggested by Avi.
Reviewed-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
Cc: Avi Kivity <avi@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
|
On ARM, don't map the code buffer at a fixed location, and fix up the
call/goto tcg routines to let it do long jumps.
Mapping the code buffer at a fixed address could sometimes result in it being
mapped over the top of the heap with pretty random results.
Signed-off-by: Dr. David Alan Gilbert <david.gilbert@linaro.org>
Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>
|