- miscellaneous cleanups for TCG (Emilio) and NBD (Bogdan)
- next part in the thread-safe address_space_* saga: atomic access to the bounce buffer and the map_clients list, from Fam - optional support for linking with tcmalloc, also from Fam - reapplying Peter Crosthwaite's "Respect as_translate_internal length clamp" after fixing the SPARC fallout. - build system fix from Wei Liu - small acpi-build and ioport cleanup by myself -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAABCAAGBQJVQJd4AAoJEL/70l94x66DYFYH/3ifhqWZsd4dfJri0CGAHI4i SpPmNeouc8W+F/3lwf6Inrh5NnTgd5QzoUBMQaWVkQKwUiWls8g2mXkT3jo0iDqT /B40YXnZjNm20MixNaZmk9AsOF6OqPM8EMufau874k5zTlx3tCGAW1QD+I1N7WK7 DfsFsIUD1svo2prn55fSoitMG1TIVPnpcklb4YGJRbAacQYUDhr5KAIhT1quDR2R 93BvToyQmPqRQ4YKqnJLp8HAkL4FaJumfFZVvyh2cZvyaYGN/RVdi2Dw985dJDPX /z4enE4GCAs4RDw3lZ1RDbiZDqpT2ibFgASg/arX3SxzqHirOGvMdkOjO99r9j4= =aLjh -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging - miscellaneous cleanups for TCG (Emilio) and NBD (Bogdan) - next part in the thread-safe address_space_* saga: atomic access to the bounce buffer and the map_clients list, from Fam - optional support for linking with tcmalloc, also from Fam - reapplying Peter Crosthwaite's "Respect as_translate_internal length clamp" after fixing the SPARC fallout. - build system fix from Wei Liu - small acpi-build and ioport cleanup by myself # gpg: Signature made Wed Apr 29 09:34:00 2015 BST using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (22 commits) nbd/trivial: fix type cast for ioctl translate-all: use bitmap helpers for PageDesc's bitmap target-i386: disable LINT0 after reset Makefile.target: prepend $libs_softmmu to $LIBS milkymist: do not modify libs-softmmu configure: Add support for tcmalloc exec: Respect as_translate_internal length clamp ioport: reserve the whole range of an I/O port in the AddressSpace ioport: loosen assertions on emulation of 16-bit ports ioport: remove wrong comment ide: there is only one data port gus: clean up MemoryRegionPortio sb16: remove useless mixer_write_indexw sun4m: fix slavio sysctrl and led register sizes acpi-build: remove dependency from ram_addr.h memory: add memory_region_ram_resize dma-helpers: Fix race condition of continue_after_map_failure and dma_aio_cancel exec: Notify cpu_register_map_client caller if the bounce buffer is available exec: Protect map_client_list with mutex linux-user, bsd-user: Remove two calls to cpu_exec_init_all ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
06feaacfb4
@ -134,7 +134,7 @@ obj-$(CONFIG_KVM) += kvm-all.o
|
|||||||
obj-y += memory.o savevm.o cputlb.o
|
obj-y += memory.o savevm.o cputlb.o
|
||||||
obj-y += memory_mapping.o
|
obj-y += memory_mapping.o
|
||||||
obj-y += dump.o
|
obj-y += dump.o
|
||||||
LIBS+=$(libs_softmmu)
|
LIBS := $(libs_softmmu) $(LIBS)
|
||||||
|
|
||||||
# xen support
|
# xen support
|
||||||
obj-$(CONFIG_XEN) += xen-common.o
|
obj-$(CONFIG_XEN) += xen-common.o
|
||||||
|
@ -905,7 +905,6 @@ int main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
tcg_exec_init(0);
|
tcg_exec_init(0);
|
||||||
cpu_exec_init_all();
|
|
||||||
/* NOTE: we need to init the CPU at this stage to get
|
/* NOTE: we need to init the CPU at this stage to get
|
||||||
qemu_host_page_size */
|
qemu_host_page_size */
|
||||||
cpu = cpu_init(cpu_model);
|
cpu = cpu_init(cpu_model);
|
||||||
|
24
configure
vendored
24
configure
vendored
@ -336,6 +336,7 @@ libssh2=""
|
|||||||
vhdx=""
|
vhdx=""
|
||||||
quorum=""
|
quorum=""
|
||||||
numa=""
|
numa=""
|
||||||
|
tcmalloc="no"
|
||||||
|
|
||||||
# parse CC options first
|
# parse CC options first
|
||||||
for opt do
|
for opt do
|
||||||
@ -1134,6 +1135,10 @@ for opt do
|
|||||||
;;
|
;;
|
||||||
--enable-numa) numa="yes"
|
--enable-numa) numa="yes"
|
||||||
;;
|
;;
|
||||||
|
--disable-tcmalloc) tcmalloc="no"
|
||||||
|
;;
|
||||||
|
--enable-tcmalloc) tcmalloc="yes"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "ERROR: unknown option $opt"
|
echo "ERROR: unknown option $opt"
|
||||||
echo "Try '$0 --help' for more information"
|
echo "Try '$0 --help' for more information"
|
||||||
@ -1407,6 +1412,8 @@ Advanced options (experts only):
|
|||||||
--enable-quorum enable quorum block filter support
|
--enable-quorum enable quorum block filter support
|
||||||
--disable-numa disable libnuma support
|
--disable-numa disable libnuma support
|
||||||
--enable-numa enable libnuma support
|
--enable-numa enable libnuma support
|
||||||
|
--disable-tcmalloc disable tcmalloc support
|
||||||
|
--enable-tcmalloc enable tcmalloc support
|
||||||
|
|
||||||
NOTE: The object files are built at the place where configure is launched
|
NOTE: The object files are built at the place where configure is launched
|
||||||
EOF
|
EOF
|
||||||
@ -3330,6 +3337,22 @@ EOF
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
# tcmalloc probe
|
||||||
|
|
||||||
|
if test "$tcmalloc" = "yes" ; then
|
||||||
|
cat > $TMPC << EOF
|
||||||
|
#include <stdlib.h>
|
||||||
|
int main(void) { malloc(1); return 0; }
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if compile_prog "" "-ltcmalloc" ; then
|
||||||
|
LIBS="-ltcmalloc $LIBS"
|
||||||
|
else
|
||||||
|
feature_not_found "tcmalloc" "install gperftools devel"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
# signalfd probe
|
# signalfd probe
|
||||||
signalfd="no"
|
signalfd="no"
|
||||||
@ -4441,6 +4464,7 @@ echo "lzo support $lzo"
|
|||||||
echo "snappy support $snappy"
|
echo "snappy support $snappy"
|
||||||
echo "bzip2 support $bzip2"
|
echo "bzip2 support $bzip2"
|
||||||
echo "NUMA host support $numa"
|
echo "NUMA host support $numa"
|
||||||
|
echo "tcmalloc support $tcmalloc"
|
||||||
|
|
||||||
if test "$sdl_too_old" = "yes"; then
|
if test "$sdl_too_old" = "yes"; then
|
||||||
echo "-> Your SDL version is too old - please upgrade to have SDL support"
|
echo "-> Your SDL version is too old - please upgrade to have SDL support"
|
||||||
|
@ -93,14 +93,6 @@ static void reschedule_dma(void *opaque)
|
|||||||
dma_blk_cb(dbs, 0);
|
dma_blk_cb(dbs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void continue_after_map_failure(void *opaque)
|
|
||||||
{
|
|
||||||
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
|
|
||||||
|
|
||||||
dbs->bh = qemu_bh_new(reschedule_dma, dbs);
|
|
||||||
qemu_bh_schedule(dbs->bh);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dma_blk_unmap(DMAAIOCB *dbs)
|
static void dma_blk_unmap(DMAAIOCB *dbs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -162,7 +154,9 @@ static void dma_blk_cb(void *opaque, int ret)
|
|||||||
|
|
||||||
if (dbs->iov.size == 0) {
|
if (dbs->iov.size == 0) {
|
||||||
trace_dma_map_wait(dbs);
|
trace_dma_map_wait(dbs);
|
||||||
cpu_register_map_client(dbs, continue_after_map_failure);
|
dbs->bh = aio_bh_new(blk_get_aio_context(dbs->blk),
|
||||||
|
reschedule_dma, dbs);
|
||||||
|
cpu_register_map_client(dbs->bh);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,6 +178,11 @@ static void dma_aio_cancel(BlockAIOCB *acb)
|
|||||||
if (dbs->acb) {
|
if (dbs->acb) {
|
||||||
blk_aio_cancel_async(dbs->acb);
|
blk_aio_cancel_async(dbs->acb);
|
||||||
}
|
}
|
||||||
|
if (dbs->bh) {
|
||||||
|
cpu_unregister_map_client(dbs->bh);
|
||||||
|
qemu_bh_delete(dbs->bh);
|
||||||
|
dbs->bh = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
85
exec.c
85
exec.c
@ -380,7 +380,6 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
|||||||
IOMMUTLBEntry iotlb;
|
IOMMUTLBEntry iotlb;
|
||||||
MemoryRegionSection *section;
|
MemoryRegionSection *section;
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
hwaddr len = *plen;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -395,7 +394,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
|||||||
iotlb = mr->iommu_ops->translate(mr, addr, is_write);
|
iotlb = mr->iommu_ops->translate(mr, addr, is_write);
|
||||||
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
|
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
|
||||||
| (addr & iotlb.addr_mask));
|
| (addr & iotlb.addr_mask));
|
||||||
len = MIN(len, (addr | iotlb.addr_mask) - addr + 1);
|
*plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
|
||||||
if (!(iotlb.perm & (1 << is_write))) {
|
if (!(iotlb.perm & (1 << is_write))) {
|
||||||
mr = &io_mem_unassigned;
|
mr = &io_mem_unassigned;
|
||||||
break;
|
break;
|
||||||
@ -406,10 +405,9 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
|||||||
|
|
||||||
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
|
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
|
||||||
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
|
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
|
||||||
len = MIN(page, len);
|
*plen = MIN(page, *plen);
|
||||||
}
|
}
|
||||||
|
|
||||||
*plen = len;
|
|
||||||
*xlat = addr;
|
*xlat = addr;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return mr;
|
return mr;
|
||||||
@ -429,15 +427,6 @@ address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void cpu_exec_init_all(void)
|
|
||||||
{
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
qemu_mutex_init(&ram_list.mutex);
|
|
||||||
memory_map_init();
|
|
||||||
io_mem_init();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
|
||||||
static int cpu_common_post_load(void *opaque, int version_id)
|
static int cpu_common_post_load(void *opaque, int version_id)
|
||||||
@ -2518,48 +2507,79 @@ typedef struct {
|
|||||||
void *buffer;
|
void *buffer;
|
||||||
hwaddr addr;
|
hwaddr addr;
|
||||||
hwaddr len;
|
hwaddr len;
|
||||||
|
bool in_use;
|
||||||
} BounceBuffer;
|
} BounceBuffer;
|
||||||
|
|
||||||
static BounceBuffer bounce;
|
static BounceBuffer bounce;
|
||||||
|
|
||||||
typedef struct MapClient {
|
typedef struct MapClient {
|
||||||
void *opaque;
|
QEMUBH *bh;
|
||||||
void (*callback)(void *opaque);
|
|
||||||
QLIST_ENTRY(MapClient) link;
|
QLIST_ENTRY(MapClient) link;
|
||||||
} MapClient;
|
} MapClient;
|
||||||
|
|
||||||
|
QemuMutex map_client_list_lock;
|
||||||
static QLIST_HEAD(map_client_list, MapClient) map_client_list
|
static QLIST_HEAD(map_client_list, MapClient) map_client_list
|
||||||
= QLIST_HEAD_INITIALIZER(map_client_list);
|
= QLIST_HEAD_INITIALIZER(map_client_list);
|
||||||
|
|
||||||
void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque))
|
static void cpu_unregister_map_client_do(MapClient *client)
|
||||||
{
|
{
|
||||||
MapClient *client = g_malloc(sizeof(*client));
|
|
||||||
|
|
||||||
client->opaque = opaque;
|
|
||||||
client->callback = callback;
|
|
||||||
QLIST_INSERT_HEAD(&map_client_list, client, link);
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cpu_unregister_map_client(void *_client)
|
|
||||||
{
|
|
||||||
MapClient *client = (MapClient *)_client;
|
|
||||||
|
|
||||||
QLIST_REMOVE(client, link);
|
QLIST_REMOVE(client, link);
|
||||||
g_free(client);
|
g_free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpu_notify_map_clients(void)
|
static void cpu_notify_map_clients_locked(void)
|
||||||
{
|
{
|
||||||
MapClient *client;
|
MapClient *client;
|
||||||
|
|
||||||
while (!QLIST_EMPTY(&map_client_list)) {
|
while (!QLIST_EMPTY(&map_client_list)) {
|
||||||
client = QLIST_FIRST(&map_client_list);
|
client = QLIST_FIRST(&map_client_list);
|
||||||
client->callback(client->opaque);
|
qemu_bh_schedule(client->bh);
|
||||||
cpu_unregister_map_client(client);
|
cpu_unregister_map_client_do(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cpu_register_map_client(QEMUBH *bh)
|
||||||
|
{
|
||||||
|
MapClient *client = g_malloc(sizeof(*client));
|
||||||
|
|
||||||
|
qemu_mutex_lock(&map_client_list_lock);
|
||||||
|
client->bh = bh;
|
||||||
|
QLIST_INSERT_HEAD(&map_client_list, client, link);
|
||||||
|
if (!atomic_read(&bounce.in_use)) {
|
||||||
|
cpu_notify_map_clients_locked();
|
||||||
|
}
|
||||||
|
qemu_mutex_unlock(&map_client_list_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpu_exec_init_all(void)
|
||||||
|
{
|
||||||
|
qemu_mutex_init(&ram_list.mutex);
|
||||||
|
memory_map_init();
|
||||||
|
io_mem_init();
|
||||||
|
qemu_mutex_init(&map_client_list_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpu_unregister_map_client(QEMUBH *bh)
|
||||||
|
{
|
||||||
|
MapClient *client;
|
||||||
|
|
||||||
|
qemu_mutex_lock(&map_client_list_lock);
|
||||||
|
QLIST_FOREACH(client, &map_client_list, link) {
|
||||||
|
if (client->bh == bh) {
|
||||||
|
cpu_unregister_map_client_do(client);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qemu_mutex_unlock(&map_client_list_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cpu_notify_map_clients(void)
|
||||||
|
{
|
||||||
|
qemu_mutex_lock(&map_client_list_lock);
|
||||||
|
cpu_notify_map_clients_locked();
|
||||||
|
qemu_mutex_unlock(&map_client_list_lock);
|
||||||
|
}
|
||||||
|
|
||||||
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write)
|
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write)
|
||||||
{
|
{
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
@ -2606,7 +2626,7 @@ void *address_space_map(AddressSpace *as,
|
|||||||
l = len;
|
l = len;
|
||||||
mr = address_space_translate(as, addr, &xlat, &l, is_write);
|
mr = address_space_translate(as, addr, &xlat, &l, is_write);
|
||||||
if (!memory_access_is_direct(mr, is_write)) {
|
if (!memory_access_is_direct(mr, is_write)) {
|
||||||
if (bounce.buffer) {
|
if (atomic_xchg(&bounce.in_use, true)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Avoid unbounded allocations */
|
/* Avoid unbounded allocations */
|
||||||
@ -2678,6 +2698,7 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
|
|||||||
qemu_vfree(bounce.buffer);
|
qemu_vfree(bounce.buffer);
|
||||||
bounce.buffer = NULL;
|
bounce.buffer = NULL;
|
||||||
memory_region_unref(bounce.mr);
|
memory_region_unref(bounce.mr);
|
||||||
|
atomic_mb_set(&bounce.in_use, false);
|
||||||
cpu_notify_map_clients();
|
cpu_notify_map_clients();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,13 +71,6 @@ IO_READ_PROTO (gus_readb)
|
|||||||
return gus_read (&s->emu, nport, 1);
|
return gus_read (&s->emu, nport, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
IO_READ_PROTO (gus_readw)
|
|
||||||
{
|
|
||||||
GUSState *s = opaque;
|
|
||||||
|
|
||||||
return gus_read (&s->emu, nport, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
IO_WRITE_PROTO (gus_writeb)
|
IO_WRITE_PROTO (gus_writeb)
|
||||||
{
|
{
|
||||||
GUSState *s = opaque;
|
GUSState *s = opaque;
|
||||||
@ -85,13 +78,6 @@ IO_WRITE_PROTO (gus_writeb)
|
|||||||
gus_write (&s->emu, nport, 1, val);
|
gus_write (&s->emu, nport, 1, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
IO_WRITE_PROTO (gus_writew)
|
|
||||||
{
|
|
||||||
GUSState *s = opaque;
|
|
||||||
|
|
||||||
gus_write (&s->emu, nport, 2, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int write_audio (GUSState *s, int samples)
|
static int write_audio (GUSState *s, int samples)
|
||||||
{
|
{
|
||||||
int net = 0;
|
int net = 0;
|
||||||
@ -236,17 +222,13 @@ static const VMStateDescription vmstate_gus = {
|
|||||||
|
|
||||||
static const MemoryRegionPortio gus_portio_list1[] = {
|
static const MemoryRegionPortio gus_portio_list1[] = {
|
||||||
{0x000, 1, 1, .write = gus_writeb },
|
{0x000, 1, 1, .write = gus_writeb },
|
||||||
{0x000, 1, 2, .write = gus_writew },
|
|
||||||
{0x006, 10, 1, .read = gus_readb, .write = gus_writeb },
|
{0x006, 10, 1, .read = gus_readb, .write = gus_writeb },
|
||||||
{0x006, 10, 2, .read = gus_readw, .write = gus_writew },
|
|
||||||
{0x100, 8, 1, .read = gus_readb, .write = gus_writeb },
|
{0x100, 8, 1, .read = gus_readb, .write = gus_writeb },
|
||||||
{0x100, 8, 2, .read = gus_readw, .write = gus_writew },
|
|
||||||
PORTIO_END_OF_LIST (),
|
PORTIO_END_OF_LIST (),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const MemoryRegionPortio gus_portio_list2[] = {
|
static const MemoryRegionPortio gus_portio_list2[] = {
|
||||||
{0, 1, 1, .read = gus_readb },
|
{0, 2, 1, .read = gus_readb },
|
||||||
{0, 1, 2, .read = gus_readw },
|
|
||||||
PORTIO_END_OF_LIST (),
|
PORTIO_END_OF_LIST (),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1121,12 +1121,6 @@ static IO_WRITE_PROTO (mixer_write_datab)
|
|||||||
s->mixer_regs[s->mixer_nreg] = val;
|
s->mixer_regs[s->mixer_nreg] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IO_WRITE_PROTO (mixer_write_indexw)
|
|
||||||
{
|
|
||||||
mixer_write_indexb (opaque, nport, val & 0xff);
|
|
||||||
mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
static IO_READ_PROTO (mixer_read)
|
static IO_READ_PROTO (mixer_read)
|
||||||
{
|
{
|
||||||
SB16State *s = opaque;
|
SB16State *s = opaque;
|
||||||
@ -1345,7 +1339,6 @@ static const VMStateDescription vmstate_sb16 = {
|
|||||||
|
|
||||||
static const MemoryRegionPortio sb16_ioport_list[] = {
|
static const MemoryRegionPortio sb16_ioport_list[] = {
|
||||||
{ 4, 1, 1, .write = mixer_write_indexb },
|
{ 4, 1, 1, .write = mixer_write_indexb },
|
||||||
{ 4, 1, 2, .write = mixer_write_indexw },
|
|
||||||
{ 5, 1, 1, .read = mixer_read, .write = mixer_write_datab },
|
{ 5, 1, 1, .read = mixer_read, .write = mixer_write_datab },
|
||||||
{ 6, 1, 1, .read = dsp_read, .write = dsp_write },
|
{ 6, 1, 1, .read = dsp_read, .write = dsp_write },
|
||||||
{ 10, 1, 1, .read = dsp_read },
|
{ 10, 1, 1, .read = dsp_read },
|
||||||
|
@ -835,12 +835,12 @@ err:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
|
MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
|
||||||
size_t max_len, hwaddr addr, const char *fw_file_name,
|
size_t max_len, hwaddr addr, const char *fw_file_name,
|
||||||
FWCfgReadCallback fw_callback, void *callback_opaque)
|
FWCfgReadCallback fw_callback, void *callback_opaque)
|
||||||
{
|
{
|
||||||
Rom *rom;
|
Rom *rom;
|
||||||
ram_addr_t ret = RAM_ADDR_MAX;
|
MemoryRegion *mr = NULL;
|
||||||
|
|
||||||
rom = g_malloc0(sizeof(*rom));
|
rom = g_malloc0(sizeof(*rom));
|
||||||
rom->name = g_strdup(name);
|
rom->name = g_strdup(name);
|
||||||
@ -858,7 +858,7 @@ ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
|
|||||||
|
|
||||||
if (rom_file_has_mr) {
|
if (rom_file_has_mr) {
|
||||||
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
|
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
|
||||||
ret = memory_region_get_ram_addr(rom->mr);
|
mr = rom->mr;
|
||||||
} else {
|
} else {
|
||||||
data = rom->data;
|
data = rom->data;
|
||||||
}
|
}
|
||||||
@ -867,7 +867,7 @@ ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
|
|||||||
fw_callback, callback_opaque,
|
fw_callback, callback_opaque,
|
||||||
data, rom->datasize);
|
data, rom->datasize);
|
||||||
}
|
}
|
||||||
return ret;
|
return mr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is specific for elf program because we don't need to allocate
|
/* This function is specific for elf program because we don't need to allocate
|
||||||
|
@ -21,7 +21,7 @@ common-obj-$(CONFIG_ZAURUS) += tc6393xb.o
|
|||||||
ifeq ($(CONFIG_MILKYMIST_TMU2),y)
|
ifeq ($(CONFIG_MILKYMIST_TMU2),y)
|
||||||
common-obj-y += milkymist-tmu2.o
|
common-obj-y += milkymist-tmu2.o
|
||||||
milkymist-tmu2.o-cflags := $(OPENGL_CFLAGS)
|
milkymist-tmu2.o-cflags := $(OPENGL_CFLAGS)
|
||||||
libs_softmmu += $(OPENGL_LIBS)
|
milkymist-tmu2.o-libs += $(OPENGL_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
obj-$(CONFIG_OMAP) += omap_dss.o
|
obj-$(CONFIG_OMAP) += omap_dss.o
|
||||||
|
@ -58,7 +58,6 @@
|
|||||||
|
|
||||||
#include "qapi/qmp/qint.h"
|
#include "qapi/qmp/qint.h"
|
||||||
#include "qom/qom-qobject.h"
|
#include "qom/qom-qobject.h"
|
||||||
#include "exec/ram_addr.h"
|
|
||||||
|
|
||||||
/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
|
/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
|
||||||
* -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
|
* -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
|
||||||
@ -1323,13 +1322,13 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
|
|||||||
typedef
|
typedef
|
||||||
struct AcpiBuildState {
|
struct AcpiBuildState {
|
||||||
/* Copy of table in RAM (for patching). */
|
/* Copy of table in RAM (for patching). */
|
||||||
ram_addr_t table_ram;
|
MemoryRegion *table_mr;
|
||||||
/* Is table patched? */
|
/* Is table patched? */
|
||||||
uint8_t patched;
|
uint8_t patched;
|
||||||
PcGuestInfo *guest_info;
|
PcGuestInfo *guest_info;
|
||||||
void *rsdp;
|
void *rsdp;
|
||||||
ram_addr_t rsdp_ram;
|
MemoryRegion *rsdp_mr;
|
||||||
ram_addr_t linker_ram;
|
MemoryRegion *linker_mr;
|
||||||
} AcpiBuildState;
|
} AcpiBuildState;
|
||||||
|
|
||||||
static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
|
static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
|
||||||
@ -1513,15 +1512,15 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
|||||||
g_array_free(table_offsets, true);
|
g_array_free(table_offsets, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void acpi_ram_update(ram_addr_t ram, GArray *data)
|
static void acpi_ram_update(MemoryRegion *mr, GArray *data)
|
||||||
{
|
{
|
||||||
uint32_t size = acpi_data_len(data);
|
uint32_t size = acpi_data_len(data);
|
||||||
|
|
||||||
/* Make sure RAM size is correct - in case it got changed e.g. by migration */
|
/* Make sure RAM size is correct - in case it got changed e.g. by migration */
|
||||||
qemu_ram_resize(ram, size, &error_abort);
|
memory_region_ram_resize(mr, size, &error_abort);
|
||||||
|
|
||||||
memcpy(qemu_get_ram_ptr(ram), data->data, size);
|
memcpy(memory_region_get_ram_ptr(mr), data->data, size);
|
||||||
cpu_physical_memory_set_dirty_range_nocode(ram, size);
|
memory_region_set_dirty(mr, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void acpi_build_update(void *build_opaque, uint32_t offset)
|
static void acpi_build_update(void *build_opaque, uint32_t offset)
|
||||||
@ -1539,15 +1538,15 @@ static void acpi_build_update(void *build_opaque, uint32_t offset)
|
|||||||
|
|
||||||
acpi_build(build_state->guest_info, &tables);
|
acpi_build(build_state->guest_info, &tables);
|
||||||
|
|
||||||
acpi_ram_update(build_state->table_ram, tables.table_data);
|
acpi_ram_update(build_state->table_mr, tables.table_data);
|
||||||
|
|
||||||
if (build_state->rsdp) {
|
if (build_state->rsdp) {
|
||||||
memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp));
|
memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp));
|
||||||
} else {
|
} else {
|
||||||
acpi_ram_update(build_state->rsdp_ram, tables.rsdp);
|
acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
acpi_ram_update(build_state->linker_ram, tables.linker);
|
acpi_ram_update(build_state->linker_mr, tables.linker);
|
||||||
acpi_build_tables_cleanup(&tables, true);
|
acpi_build_tables_cleanup(&tables, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1557,8 +1556,9 @@ static void acpi_build_reset(void *build_opaque)
|
|||||||
build_state->patched = 0;
|
build_state->patched = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ram_addr_t acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob,
|
static MemoryRegion *acpi_add_rom_blob(AcpiBuildState *build_state,
|
||||||
const char *name, uint64_t max_size)
|
GArray *blob, const char *name,
|
||||||
|
uint64_t max_size)
|
||||||
{
|
{
|
||||||
return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
|
return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
|
||||||
name, acpi_build_update, build_state);
|
name, acpi_build_update, build_state);
|
||||||
@ -1604,12 +1604,12 @@ void acpi_setup(PcGuestInfo *guest_info)
|
|||||||
acpi_build(build_state->guest_info, &tables);
|
acpi_build(build_state->guest_info, &tables);
|
||||||
|
|
||||||
/* Now expose it all to Guest */
|
/* Now expose it all to Guest */
|
||||||
build_state->table_ram = acpi_add_rom_blob(build_state, tables.table_data,
|
build_state->table_mr = acpi_add_rom_blob(build_state, tables.table_data,
|
||||||
ACPI_BUILD_TABLE_FILE,
|
ACPI_BUILD_TABLE_FILE,
|
||||||
ACPI_BUILD_TABLE_MAX_SIZE);
|
ACPI_BUILD_TABLE_MAX_SIZE);
|
||||||
assert(build_state->table_ram != RAM_ADDR_MAX);
|
assert(build_state->table_mr != NULL);
|
||||||
|
|
||||||
build_state->linker_ram =
|
build_state->linker_mr =
|
||||||
acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
|
acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
|
||||||
|
|
||||||
fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
|
fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
|
||||||
@ -1627,10 +1627,10 @@ void acpi_setup(PcGuestInfo *guest_info)
|
|||||||
fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
|
fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
|
||||||
acpi_build_update, build_state,
|
acpi_build_update, build_state,
|
||||||
build_state->rsdp, rsdp_size);
|
build_state->rsdp, rsdp_size);
|
||||||
build_state->rsdp_ram = (ram_addr_t)-1;
|
build_state->rsdp_mr = NULL;
|
||||||
} else {
|
} else {
|
||||||
build_state->rsdp = NULL;
|
build_state->rsdp = NULL;
|
||||||
build_state->rsdp_ram = acpi_add_rom_blob(build_state, tables.rsdp,
|
build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,
|
||||||
ACPI_BUILD_RSDP_FILE, 0);
|
ACPI_BUILD_RSDP_FILE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2436,8 +2436,8 @@ void ide_init2(IDEBus *bus, qemu_irq irq)
|
|||||||
|
|
||||||
static const MemoryRegionPortio ide_portio_list[] = {
|
static const MemoryRegionPortio ide_portio_list[] = {
|
||||||
{ 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
|
{ 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
|
||||||
{ 0, 2, 2, .read = ide_data_readw, .write = ide_data_writew },
|
{ 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew },
|
||||||
{ 0, 4, 4, .read = ide_data_readl, .write = ide_data_writel },
|
{ 0, 1, 4, .read = ide_data_readl, .write = ide_data_writel },
|
||||||
PORTIO_END_OF_LIST(),
|
PORTIO_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -243,15 +243,6 @@ static void apic_reset_common(DeviceState *dev)
|
|||||||
info->vapic_base_update(s);
|
info->vapic_base_update(s);
|
||||||
|
|
||||||
apic_init_reset(dev);
|
apic_init_reset(dev);
|
||||||
|
|
||||||
if (bsp) {
|
|
||||||
/*
|
|
||||||
* LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
|
|
||||||
* time typically by BIOS, so PIC interrupt can be delivered to the
|
|
||||||
* processor when local APIC is enabled.
|
|
||||||
*/
|
|
||||||
s->lvt[APIC_LVT_LINT0] = 0x700;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is only used for old state version 1 and 2 */
|
/* This function is only used for old state version 1 and 2 */
|
||||||
|
@ -68,6 +68,7 @@ typedef struct APCState {
|
|||||||
} APCState;
|
} APCState;
|
||||||
|
|
||||||
#define MISC_SIZE 1
|
#define MISC_SIZE 1
|
||||||
|
#define LED_SIZE 2
|
||||||
#define SYSCTRL_SIZE 4
|
#define SYSCTRL_SIZE 4
|
||||||
|
|
||||||
#define AUX1_TC 0x02
|
#define AUX1_TC 0x02
|
||||||
@ -452,13 +453,13 @@ static int slavio_misc_init1(SysBusDevice *sbd)
|
|||||||
/* 16 bit registers */
|
/* 16 bit registers */
|
||||||
/* ss600mp diag LEDs */
|
/* ss600mp diag LEDs */
|
||||||
memory_region_init_io(&s->led_iomem, OBJECT(s), &slavio_led_mem_ops, s,
|
memory_region_init_io(&s->led_iomem, OBJECT(s), &slavio_led_mem_ops, s,
|
||||||
"leds", MISC_SIZE);
|
"leds", LED_SIZE);
|
||||||
sysbus_init_mmio(sbd, &s->led_iomem);
|
sysbus_init_mmio(sbd, &s->led_iomem);
|
||||||
|
|
||||||
/* 32 bit registers */
|
/* 32 bit registers */
|
||||||
/* System control */
|
/* System control */
|
||||||
memory_region_init_io(&s->sysctrl_iomem, OBJECT(s), &slavio_sysctrl_mem_ops, s,
|
memory_region_init_io(&s->sysctrl_iomem, OBJECT(s), &slavio_sysctrl_mem_ops, s,
|
||||||
"system-control", MISC_SIZE);
|
"system-control", SYSCTRL_SIZE);
|
||||||
sysbus_init_mmio(sbd, &s->sysctrl_iomem);
|
sysbus_init_mmio(sbd, &s->sysctrl_iomem);
|
||||||
|
|
||||||
/* AUX 1 (Misc System Functions) */
|
/* AUX 1 (Misc System Functions) */
|
||||||
|
@ -82,7 +82,8 @@ void *cpu_physical_memory_map(hwaddr addr,
|
|||||||
int is_write);
|
int is_write);
|
||||||
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
|
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
|
||||||
int is_write, hwaddr access_len);
|
int is_write, hwaddr access_len);
|
||||||
void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque));
|
void cpu_register_map_client(QEMUBH *bh);
|
||||||
|
void cpu_unregister_map_client(QEMUBH *bh);
|
||||||
|
|
||||||
bool cpu_physical_memory_is_io(hwaddr phys_addr);
|
bool cpu_physical_memory_is_io(hwaddr phys_addr);
|
||||||
|
|
||||||
|
@ -627,6 +627,18 @@ int memory_region_get_fd(MemoryRegion *mr);
|
|||||||
*/
|
*/
|
||||||
void *memory_region_get_ram_ptr(MemoryRegion *mr);
|
void *memory_region_get_ram_ptr(MemoryRegion *mr);
|
||||||
|
|
||||||
|
/* memory_region_ram_resize: Resize a RAM region.
|
||||||
|
*
|
||||||
|
* Only legal before guest might have detected the memory size: e.g. on
|
||||||
|
* incoming migration, or right after reset.
|
||||||
|
*
|
||||||
|
* @mr: a memory region created with @memory_region_init_resizeable_ram.
|
||||||
|
* @newsize: the new size the region
|
||||||
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
|
*/
|
||||||
|
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* memory_region_set_log: Turn dirty logging on or off for a region.
|
* memory_region_set_log: Turn dirty logging on or off for a region.
|
||||||
*
|
*
|
||||||
|
@ -68,9 +68,11 @@ extern bool rom_file_has_mr;
|
|||||||
int rom_add_file(const char *file, const char *fw_dir,
|
int rom_add_file(const char *file, const char *fw_dir,
|
||||||
hwaddr addr, int32_t bootindex,
|
hwaddr addr, int32_t bootindex,
|
||||||
bool option_rom);
|
bool option_rom);
|
||||||
ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
|
MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
|
||||||
size_t max_len, hwaddr addr, const char *fw_file_name,
|
size_t max_len, hwaddr addr,
|
||||||
FWCfgReadCallback fw_callback, void *callback_opaque);
|
const char *fw_file_name,
|
||||||
|
FWCfgReadCallback fw_callback,
|
||||||
|
void *callback_opaque);
|
||||||
int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
||||||
size_t romsize, hwaddr addr);
|
size_t romsize, hwaddr addr);
|
||||||
int rom_load_all(void);
|
int rom_load_all(void);
|
||||||
|
26
ioport.c
26
ioport.c
@ -191,9 +191,14 @@ static uint64_t portio_read(void *opaque, hwaddr addr, unsigned size)
|
|||||||
data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
|
data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
|
||||||
} else if (size == 2) {
|
} else if (size == 2) {
|
||||||
mrp = find_portio(mrpio, addr, 1, false);
|
mrp = find_portio(mrpio, addr, 1, false);
|
||||||
assert(mrp);
|
if (mrp) {
|
||||||
data = mrp->read(mrpio->portio_opaque, mrp->base + addr) |
|
data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
|
||||||
(mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) << 8);
|
if (addr + 1 < mrp->offset + mrp->len) {
|
||||||
|
data |= mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) << 8;
|
||||||
|
} else {
|
||||||
|
data |= 0xff00;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -208,11 +213,14 @@ static void portio_write(void *opaque, hwaddr addr, uint64_t data,
|
|||||||
mrp->write(mrpio->portio_opaque, mrp->base + addr, data);
|
mrp->write(mrpio->portio_opaque, mrp->base + addr, data);
|
||||||
} else if (size == 2) {
|
} else if (size == 2) {
|
||||||
mrp = find_portio(mrpio, addr, 1, true);
|
mrp = find_portio(mrpio, addr, 1, true);
|
||||||
assert(mrp);
|
if (mrp) {
|
||||||
mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff);
|
mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff);
|
||||||
|
if (addr + 1 < mrp->offset + mrp->len) {
|
||||||
mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 8);
|
mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps portio_ops = {
|
static const MemoryRegionOps portio_ops = {
|
||||||
.read = portio_read,
|
.read = portio_read,
|
||||||
@ -243,10 +251,6 @@ static void portio_list_add_1(PortioList *piolist,
|
|||||||
mrpio->ports[i].base = start + off_low;
|
mrpio->ports[i].base = start + off_low;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Use an alias so that the callback is called with an absolute address,
|
|
||||||
* rather than an offset relative to to start + off_low.
|
|
||||||
*/
|
|
||||||
memory_region_init_io(&mrpio->mr, piolist->owner, &portio_ops, mrpio,
|
memory_region_init_io(&mrpio->mr, piolist->owner, &portio_ops, mrpio,
|
||||||
piolist->name, off_high - off_low);
|
piolist->name, off_high - off_low);
|
||||||
if (piolist->flush_coalesced_mmio) {
|
if (piolist->flush_coalesced_mmio) {
|
||||||
@ -269,7 +273,7 @@ void portio_list_add(PortioList *piolist,
|
|||||||
|
|
||||||
/* Handle the first entry specially. */
|
/* Handle the first entry specially. */
|
||||||
off_last = off_low = pio_start->offset;
|
off_last = off_low = pio_start->offset;
|
||||||
off_high = off_low + pio_start->len;
|
off_high = off_low + pio_start->len + pio_start->size - 1;
|
||||||
count = 1;
|
count = 1;
|
||||||
|
|
||||||
for (pio = pio_start + 1; pio->size != 0; pio++, count++) {
|
for (pio = pio_start + 1; pio->size != 0; pio++, count++) {
|
||||||
@ -284,10 +288,10 @@ void portio_list_add(PortioList *piolist,
|
|||||||
/* ... and start collecting anew. */
|
/* ... and start collecting anew. */
|
||||||
pio_start = pio;
|
pio_start = pio;
|
||||||
off_low = off_last;
|
off_low = off_last;
|
||||||
off_high = off_low + pio->len;
|
off_high = off_low + pio->len + pio_start->size - 1;
|
||||||
count = 0;
|
count = 0;
|
||||||
} else if (off_last + pio->len > off_high) {
|
} else if (off_last + pio->len > off_high) {
|
||||||
off_high = off_last + pio->len;
|
off_high = off_last + pio->len + pio_start->size - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3934,7 +3934,6 @@ int main(int argc, char **argv, char **envp)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
tcg_exec_init(0);
|
tcg_exec_init(0);
|
||||||
cpu_exec_init_all();
|
|
||||||
/* NOTE: we need to init the CPU at this stage to get
|
/* NOTE: we need to init the CPU at this stage to get
|
||||||
qemu_host_page_size */
|
qemu_host_page_size */
|
||||||
cpu = cpu_init(cpu_model);
|
cpu = cpu_init(cpu_model);
|
||||||
|
7
memory.c
7
memory.c
@ -1523,6 +1523,13 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
|
|||||||
return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
|
return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp)
|
||||||
|
{
|
||||||
|
assert(mr->terminates);
|
||||||
|
|
||||||
|
qemu_ram_resize(mr->ram_addr, newsize, errp);
|
||||||
|
}
|
||||||
|
|
||||||
static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
|
static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
|
||||||
{
|
{
|
||||||
FlatView *view;
|
FlatView *view;
|
||||||
|
2
nbd.c
2
nbd.c
@ -681,7 +681,7 @@ int nbd_init(int fd, int csock, uint32_t flags, off_t size)
|
|||||||
|
|
||||||
TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE));
|
TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE));
|
||||||
|
|
||||||
if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / (size_t)BDRV_SECTOR_SIZE) < 0) {
|
if (ioctl(fd, NBD_SET_SIZE_BLOCKS, (size_t)(size / BDRV_SECTOR_SIZE)) < 0) {
|
||||||
int serrno = errno;
|
int serrno = errno;
|
||||||
LOG("Failed setting size (in blocks)");
|
LOG("Failed setting size (in blocks)");
|
||||||
return -serrno;
|
return -serrno;
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
|
|
||||||
#include "exec/cputlb.h"
|
#include "exec/cputlb.h"
|
||||||
#include "translate-all.h"
|
#include "translate-all.h"
|
||||||
|
#include "qemu/bitmap.h"
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
|
|
||||||
//#define DEBUG_TB_INVALIDATE
|
//#define DEBUG_TB_INVALIDATE
|
||||||
@ -79,7 +80,7 @@ typedef struct PageDesc {
|
|||||||
/* in order to optimize self modifying code, we count the number
|
/* in order to optimize self modifying code, we count the number
|
||||||
of lookups we do to a given page to use a bitmap */
|
of lookups we do to a given page to use a bitmap */
|
||||||
unsigned int code_write_count;
|
unsigned int code_write_count;
|
||||||
uint8_t *code_bitmap;
|
unsigned long *code_bitmap;
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
#endif
|
#endif
|
||||||
@ -389,18 +390,6 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
|
|||||||
void **lp;
|
void **lp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
/* We can't use g_malloc because it may recurse into a locked mutex. */
|
|
||||||
# define ALLOC(P, SIZE) \
|
|
||||||
do { \
|
|
||||||
P = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, \
|
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
|
|
||||||
} while (0)
|
|
||||||
#else
|
|
||||||
# define ALLOC(P, SIZE) \
|
|
||||||
do { P = g_malloc0(SIZE); } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Level 1. Always allocated. */
|
/* Level 1. Always allocated. */
|
||||||
lp = l1_map + ((index >> V_L1_SHIFT) & (V_L1_SIZE - 1));
|
lp = l1_map + ((index >> V_L1_SHIFT) & (V_L1_SIZE - 1));
|
||||||
|
|
||||||
@ -412,7 +401,7 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
|
|||||||
if (!alloc) {
|
if (!alloc) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ALLOC(p, sizeof(void *) * V_L2_SIZE);
|
p = g_new0(void *, V_L2_SIZE);
|
||||||
*lp = p;
|
*lp = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,12 +413,10 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
|
|||||||
if (!alloc) {
|
if (!alloc) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ALLOC(pd, sizeof(PageDesc) * V_L2_SIZE);
|
pd = g_new0(PageDesc, V_L2_SIZE);
|
||||||
*lp = pd;
|
*lp = pd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef ALLOC
|
|
||||||
|
|
||||||
return pd + (index & (V_L2_SIZE - 1));
|
return pd + (index & (V_L2_SIZE - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,39 +965,12 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
|
|||||||
tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
|
tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void set_bits(uint8_t *tab, int start, int len)
|
|
||||||
{
|
|
||||||
int end, mask, end1;
|
|
||||||
|
|
||||||
end = start + len;
|
|
||||||
tab += start >> 3;
|
|
||||||
mask = 0xff << (start & 7);
|
|
||||||
if ((start & ~7) == (end & ~7)) {
|
|
||||||
if (start < end) {
|
|
||||||
mask &= ~(0xff << (end & 7));
|
|
||||||
*tab |= mask;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*tab++ |= mask;
|
|
||||||
start = (start + 8) & ~7;
|
|
||||||
end1 = end & ~7;
|
|
||||||
while (start < end1) {
|
|
||||||
*tab++ = 0xff;
|
|
||||||
start += 8;
|
|
||||||
}
|
|
||||||
if (start < end) {
|
|
||||||
mask = ~(0xff << (end & 7));
|
|
||||||
*tab |= mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void build_page_bitmap(PageDesc *p)
|
static void build_page_bitmap(PageDesc *p)
|
||||||
{
|
{
|
||||||
int n, tb_start, tb_end;
|
int n, tb_start, tb_end;
|
||||||
TranslationBlock *tb;
|
TranslationBlock *tb;
|
||||||
|
|
||||||
p->code_bitmap = g_malloc0(TARGET_PAGE_SIZE / 8);
|
p->code_bitmap = bitmap_new(TARGET_PAGE_SIZE);
|
||||||
|
|
||||||
tb = p->first_tb;
|
tb = p->first_tb;
|
||||||
while (tb != NULL) {
|
while (tb != NULL) {
|
||||||
@ -1029,7 +989,7 @@ static void build_page_bitmap(PageDesc *p)
|
|||||||
tb_start = 0;
|
tb_start = 0;
|
||||||
tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
|
tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
|
||||||
}
|
}
|
||||||
set_bits(p->code_bitmap, tb_start, tb_end - tb_start);
|
bitmap_set(p->code_bitmap, tb_start, tb_end - tb_start);
|
||||||
tb = tb->page_next[n];
|
tb = tb->page_next[n];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1219,7 +1179,6 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
|
|||||||
void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
|
void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
|
||||||
{
|
{
|
||||||
PageDesc *p;
|
PageDesc *p;
|
||||||
int offset, b;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (1) {
|
if (1) {
|
||||||
@ -1235,8 +1194,11 @@ void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (p->code_bitmap) {
|
if (p->code_bitmap) {
|
||||||
offset = start & ~TARGET_PAGE_MASK;
|
unsigned int nr;
|
||||||
b = p->code_bitmap[offset >> 3] >> (offset & 7);
|
unsigned long b;
|
||||||
|
|
||||||
|
nr = start & ~TARGET_PAGE_MASK;
|
||||||
|
b = p->code_bitmap[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG - 1));
|
||||||
if (b & ((1 << len) - 1)) {
|
if (b & ((1 << len) - 1)) {
|
||||||
goto do_invalidate;
|
goto do_invalidate;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user